blob: 24a8752a2ee576f1c7faff34cf8be4cfee7b977d [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>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060046#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080047#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080048#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060049#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020050
Ed Tanous1abe55e2018-09-05 08:30:59 -070051namespace redfish
52{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020053
Abhishek Patel5c3e9272021-06-24 10:11:33 -050054const static std::array<std::pair<std::string_view, std::string_view>, 2>
55 protocolToDBusForSystems{
56 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
57
Alpana Kumari9d3ae102019-04-12 06:49:32 -050058/**
59 * @brief Updates the Functional State of DIMMs
60 *
Ed Tanousac106bf2023-06-07 09:24:59 -070061 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050062 * @param[in] dimmState Dimm's Functional state, true/false
63 *
64 * @return None.
65 */
zhanghch058d1b46d2021-04-01 11:18:24 +080066inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070067 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070068 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050069{
Ed Tanous62598e32023-07-17 17:06:25 -070070 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050071
Gunnar Mills4e0453b2020-07-08 14:00:30 -050072 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050073 // Update STATE only if previous State was DISABLED and current Dimm is
74 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070075 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070076 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050077 if (prevMemSummary == "Disabled")
78 {
Ed Tanouse05aec52022-01-25 10:28:56 -080079 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050080 {
Ed Tanousac106bf2023-06-07 09:24:59 -070081 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050082 "Enabled";
83 }
84 }
85}
86
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050087/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050088 * @brief Update "ProcessorSummary" "Status" "State" based on
89 * CPU Functional State
90 *
Ed Tanousac106bf2023-06-07 09:24:59 -070091 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050092 * @param[in] cpuFunctionalState is CPU functional true/false
93 *
94 * @return None.
95 */
Ed Tanousac106bf2023-06-07 09:24:59 -070096inline void modifyCpuFunctionalState(
97 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098{
Ed Tanous62598e32023-07-17 17:06:25 -070099 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500100
Ed Tanous02cad962022-06-30 16:50:15 -0700101 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700102 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500103
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500104 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500105 // Update STATE only if previous State was Non_Functional and current CPU is
106 // Functional.
107 if (prevProcState == "Disabled")
108 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800109 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500110 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700111 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500112 "Enabled";
113 }
114 }
115}
116
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500117/*
118 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
119 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700120 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500121 * @param[in] cpuPresenceState CPU present or not
122 *
123 * @return None.
124 */
125inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700126 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500127 bool isCpuPresent)
128{
Ed Tanous62598e32023-07-17 17:06:25 -0700129 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500130
131 if (isCpuPresent)
132 {
133 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700134 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500135 auto* procCountPtr =
136 procCount.get_ptr<nlohmann::json::number_integer_t*>();
137 if (procCountPtr != nullptr)
138 {
139 // shouldn't be possible to be nullptr
140 *procCountPtr += 1;
141 }
142 }
143}
144
Ali Ahmed382d6472021-09-03 16:53:53 -0500145inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700146 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500147 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
148 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500149{
Ed Tanous62598e32023-07-17 17:06:25 -0700150 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500151
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200152 // TODO: Get Model
153
154 const uint16_t* coreCount = nullptr;
155
156 const bool success = sdbusplus::unpackPropertiesNoThrow(
157 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
158
159 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500160 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700161 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200162 return;
163 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500164
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200165 if (coreCount != nullptr)
166 {
167 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700168 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200169 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500170
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200171 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500172 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200173 coreCountJson = *coreCount;
174 }
175 else
176 {
177 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500178 }
179 }
180}
181
182/*
183 * @brief Get ProcessorSummary fields
184 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700185 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500186 * @param[in] service dbus service for Cpu Information
187 * @param[in] path dbus path for Cpu
188 *
189 * @return None.
190 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700191inline void
192 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
193 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500194{
Ed Tanousac106bf2023-06-07 09:24:59 -0700195 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
196 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500197 if (ec3)
198 {
Ed Tanous62598e32023-07-17 17:06:25 -0700199 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500200 return;
201 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700202 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500203 };
204
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500205 // Get the Presence of CPU
206 sdbusplus::asio::getProperty<bool>(
207 *crow::connections::systemBus, service, path,
208 "xyz.openbmc_project.Inventory.Item", "Present",
209 std::move(getCpuPresenceState));
210
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500211 if constexpr (bmcwebEnableProcMemStatus)
212 {
213 auto getCpuFunctionalState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700214 [asyncResp](const boost::system::error_code& ec3,
215 const bool cpuFunctionalCheck) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500216 if (ec3)
217 {
Ed Tanous62598e32023-07-17 17:06:25 -0700218 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500219 return;
220 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700221 modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500222 };
Ali Ahmed382d6472021-09-03 16:53:53 -0500223
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500224 // Get the Functional State
225 sdbusplus::asio::getProperty<bool>(
226 *crow::connections::systemBus, service, path,
227 "xyz.openbmc_project.State.Decorator.OperationalStatus",
228 "Functional", std::move(getCpuFunctionalState));
229 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500230
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200231 sdbusplus::asio::getAllProperties(
232 *crow::connections::systemBus, service, path,
233 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700234 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800235 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800236 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700237 if (ec2)
238 {
Ed Tanous62598e32023-07-17 17:06:25 -0700239 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700240 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700241 return;
242 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700243 getProcessorProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500244 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500245}
246
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500247/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500248 * @brief processMemoryProperties fields
249 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700250 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500251 * @param[in] service dbus service for memory Information
252 * @param[in] path dbus path for Memory
253 * @param[in] DBUS properties for memory
254 *
255 * @return None.
256 */
257inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700258 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500259 [[maybe_unused]] const std::string& service,
260 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500261 const dbus::utility::DBusPropertiesMap& properties)
262{
Ed Tanous62598e32023-07-17 17:06:25 -0700263 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500264
265 if (properties.empty())
266 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500267 if constexpr (bmcwebEnableProcMemStatus)
268 {
269 sdbusplus::asio::getProperty<bool>(
270 *crow::connections::systemBus, service, path,
271 "xyz.openbmc_project.State."
272 "Decorator.OperationalStatus",
273 "Functional",
Ed Tanousac106bf2023-06-07 09:24:59 -0700274 [asyncResp](const boost::system::error_code& ec3,
275 bool dimmState) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500276 if (ec3)
277 {
Ed Tanous62598e32023-07-17 17:06:25 -0700278 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500279 return;
280 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700281 updateDimmProperties(asyncResp, dimmState);
Patrick Williams5a39f772023-10-20 11:20:21 -0500282 });
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500283 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500284 return;
285 }
286
287 const size_t* memorySizeInKB = nullptr;
288
289 const bool success = sdbusplus::unpackPropertiesNoThrow(
290 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
291 memorySizeInKB);
292
293 if (!success)
294 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700295 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500296 return;
297 }
298
299 if (memorySizeInKB != nullptr)
300 {
301 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700302 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500303 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500304 if (preValue == nullptr)
305 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700306 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500307 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500308 }
309 else
310 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700311 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500312 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
313 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500314 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500315 if constexpr (bmcwebEnableProcMemStatus)
316 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700317 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500318 "Enabled";
319 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500320 }
321}
322
323/*
324 * @brief Get getMemorySummary fields
325 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700326 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500327 * @param[in] service dbus service for memory Information
328 * @param[in] path dbus path for memory
329 *
330 * @return None.
331 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700332inline void
333 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
334 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500335{
336 sdbusplus::asio::getAllProperties(
337 *crow::connections::systemBus, service, path,
338 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700339 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500340 path](const boost::system::error_code& ec2,
341 const dbus::utility::DBusPropertiesMap& properties) {
342 if (ec2)
343 {
Ed Tanous62598e32023-07-17 17:06:25 -0700344 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700345 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500346 return;
347 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700348 processMemoryProperties(asyncResp, service, path, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500349 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500350}
351
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500352inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
353 const boost::system::error_code& ec,
354 const dbus::utility::DBusPropertiesMap& properties)
355{
356 if (ec)
357 {
358 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
359 messages::internalError(asyncResp->res);
360 return;
361 }
362 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
363
364 const std::string* uUID = nullptr;
365
366 const bool success = sdbusplus::unpackPropertiesNoThrow(
367 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
368
369 if (!success)
370 {
371 messages::internalError(asyncResp->res);
372 return;
373 }
374
375 if (uUID != nullptr)
376 {
377 std::string valueStr = *uUID;
378 if (valueStr.size() == 32)
379 {
380 valueStr.insert(8, 1, '-');
381 valueStr.insert(13, 1, '-');
382 valueStr.insert(18, 1, '-');
383 valueStr.insert(23, 1, '-');
384 }
385 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
386 asyncResp->res.jsonValue["UUID"] = valueStr;
387 }
388}
389
390inline void
391 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
392 const boost::system::error_code& ec,
393 const dbus::utility::DBusPropertiesMap& propertiesList)
394{
395 if (ec)
396 {
397 // doesn't have to include this
398 // interface
399 return;
400 }
401 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
402
403 const std::string* partNumber = nullptr;
404 const std::string* serialNumber = nullptr;
405 const std::string* manufacturer = nullptr;
406 const std::string* model = nullptr;
407 const std::string* subModel = nullptr;
408
409 const bool success = sdbusplus::unpackPropertiesNoThrow(
410 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
411 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
412 "Model", model, "SubModel", subModel);
413
414 if (!success)
415 {
416 messages::internalError(asyncResp->res);
417 return;
418 }
419
420 if (partNumber != nullptr)
421 {
422 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
423 }
424
425 if (serialNumber != nullptr)
426 {
427 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
428 }
429
430 if (manufacturer != nullptr)
431 {
432 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
433 }
434
435 if (model != nullptr)
436 {
437 asyncResp->res.jsonValue["Model"] = *model;
438 }
439
440 if (subModel != nullptr)
441 {
442 asyncResp->res.jsonValue["SubModel"] = *subModel;
443 }
444
445 // Grab the bios version
446 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
447 "BiosVersion", false);
448}
449
450inline void
451 afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
452 const boost::system::error_code& ec,
453 const std::string& value)
454{
455 if (ec)
456 {
457 // doesn't have to include this
458 // interface
459 return;
460 }
461
462 asyncResp->res.jsonValue["AssetTag"] = value;
463}
464
465inline void afterSystemGetSubTree(
466 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
467 const std::shared_ptr<HealthPopulate>& systemHealth,
468 const boost::system::error_code& ec,
469 const dbus::utility::MapperGetSubTreeResponse& subtree)
470{
471 if (ec)
472 {
473 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
474 messages::internalError(asyncResp->res);
475 return;
476 }
477 // Iterate over all retrieved ObjectPaths.
478 for (const std::pair<
479 std::string,
480 std::vector<std::pair<std::string, std::vector<std::string>>>>&
481 object : subtree)
482 {
483 const std::string& path = object.first;
484 BMCWEB_LOG_DEBUG("Got path: {}", path);
485 const std::vector<std::pair<std::string, std::vector<std::string>>>&
486 connectionNames = object.second;
487 if (connectionNames.empty())
488 {
489 continue;
490 }
491
492 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
493 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
494
495 if constexpr (bmcwebEnableProcMemStatus)
496 {
497 memoryHealth = std::make_shared<HealthPopulate>(
498 asyncResp, "/MemorySummary/Status"_json_pointer);
499 systemHealth->children.emplace_back(memoryHealth);
500
501 if constexpr (bmcwebEnableHealthPopulate)
502 {
503 cpuHealth = std::make_shared<HealthPopulate>(
504 asyncResp, "/ProcessorSummary/Status"_json_pointer);
505
506 systemHealth->children.emplace_back(cpuHealth);
507 }
508 }
509
510 // This is not system, so check if it's cpu, dimm, UUID or
511 // BiosVer
512 for (const auto& connection : connectionNames)
513 {
514 for (const auto& interfaceName : connection.second)
515 {
516 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
517 {
518 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
519
520 getMemorySummary(asyncResp, connection.first, path);
521
522 if constexpr (bmcwebEnableProcMemStatus)
523 {
524 memoryHealth->inventory.emplace_back(path);
525 }
526 }
527 else if (interfaceName ==
528 "xyz.openbmc_project.Inventory.Item.Cpu")
529 {
530 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
531
532 getProcessorSummary(asyncResp, connection.first, path);
533
534 if constexpr (bmcwebEnableProcMemStatus)
535 {
536 cpuHealth->inventory.emplace_back(path);
537 }
538 }
539 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
540 {
541 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
542
543 sdbusplus::asio::getAllProperties(
544 *crow::connections::systemBus, connection.first, path,
545 "xyz.openbmc_project.Common.UUID",
546 [asyncResp](const boost::system::error_code& ec3,
547 const dbus::utility::DBusPropertiesMap&
548 properties) {
549 afterGetUUID(asyncResp, ec3, properties);
550 });
551 }
552 else if (interfaceName ==
553 "xyz.openbmc_project.Inventory.Item.System")
554 {
555 sdbusplus::asio::getAllProperties(
556 *crow::connections::systemBus, connection.first, path,
557 "xyz.openbmc_project.Inventory.Decorator.Asset",
558 [asyncResp](const boost::system::error_code& ec3,
559 const dbus::utility::DBusPropertiesMap&
560 properties) {
561 afterGetInventory(asyncResp, ec3, properties);
562 });
563
564 sdbusplus::asio::getProperty<std::string>(
565 *crow::connections::systemBus, connection.first, path,
566 "xyz.openbmc_project.Inventory.Decorator."
567 "AssetTag",
568 "AssetTag",
569 std::bind_front(afterGetAssetTag, asyncResp));
570 }
571 }
572 }
573 }
574}
575
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500576/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700577 * @brief Retrieves computer system properties over dbus
578 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700579 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500580 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700581 *
582 * @return None.
583 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700584inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700585 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700586 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700587{
Ed Tanous62598e32023-07-17 17:06:25 -0700588 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800589 constexpr std::array<std::string_view, 5> interfaces = {
590 "xyz.openbmc_project.Inventory.Decorator.Asset",
591 "xyz.openbmc_project.Inventory.Item.Cpu",
592 "xyz.openbmc_project.Inventory.Item.Dimm",
593 "xyz.openbmc_project.Inventory.Item.System",
594 "xyz.openbmc_project.Common.UUID",
595 };
596 dbus::utility::getSubTree(
597 "/xyz/openbmc_project/inventory", 0, interfaces,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500598 std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
Ed Tanous6c34de42018-08-29 13:37:36 -0700599}
600
601/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700602 * @brief Retrieves host state properties over dbus
603 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700604 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700605 *
606 * @return None.
607 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700608inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700609{
Ed Tanous62598e32023-07-17 17:06:25 -0700610 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700611 sdbusplus::asio::getProperty<std::string>(
612 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
613 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
614 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700615 [asyncResp](const boost::system::error_code& ec,
616 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700617 if (ec)
618 {
619 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700620 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700621 // Service not available, no error, just don't return
622 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700623 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700624 return;
625 }
Ed Tanous62598e32023-07-17 17:06:25 -0700626 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700627 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700628 return;
629 }
Ed Tanous66173382018-08-15 18:20:59 -0700630
Ed Tanous62598e32023-07-17 17:06:25 -0700631 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700632 // Verify Host State
633 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
634 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700635 asyncResp->res.jsonValue["PowerState"] = "On";
636 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700637 }
638 else if (hostState ==
639 "xyz.openbmc_project.State.Host.HostState.Quiesced")
640 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700641 asyncResp->res.jsonValue["PowerState"] = "On";
642 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700643 }
644 else if (hostState ==
645 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
646 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700647 asyncResp->res.jsonValue["PowerState"] = "On";
648 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700649 }
650 else if (
651 hostState ==
652 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
653 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700654 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
655 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700656 }
657 else if (hostState ==
658 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
659 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700660 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
661 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700662 }
663 else
664 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700665 asyncResp->res.jsonValue["PowerState"] = "Off";
666 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700667 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500668 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700669}
670
671/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500672 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530673 *
674 * @param[in] dbusSource The boot source in DBUS speak.
675 *
676 * @return Returns as a string, the boot source in Redfish terms. If translation
677 * cannot be done, returns an empty string.
678 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000679inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530680{
681 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
682 {
683 return "None";
684 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700685 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530686 {
687 return "Hdd";
688 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700689 if (dbusSource ==
690 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530691 {
692 return "Cd";
693 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700694 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530695 {
696 return "Pxe";
697 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700698 if (dbusSource ==
699 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700700 {
701 return "Usb";
702 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700703 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530704}
705
706/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300707 * @brief Translates boot type DBUS property value to redfish.
708 *
709 * @param[in] dbusType The boot type in DBUS speak.
710 *
711 * @return Returns as a string, the boot type in Redfish terms. If translation
712 * cannot be done, returns an empty string.
713 */
714inline std::string dbusToRfBootType(const std::string& dbusType)
715{
716 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
717 {
718 return "Legacy";
719 }
720 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
721 {
722 return "UEFI";
723 }
724 return "";
725}
726
727/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500728 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530729 *
730 * @param[in] dbusMode The boot mode in DBUS speak.
731 *
732 * @return Returns as a string, the boot mode in Redfish terms. If translation
733 * cannot be done, returns an empty string.
734 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000735inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530736{
737 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
738 {
739 return "None";
740 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700741 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530742 {
743 return "Diags";
744 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700745 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530746 {
747 return "BiosSetup";
748 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700749 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530750}
751
752/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600753 * @brief Translates boot progress DBUS property value to redfish.
754 *
755 * @param[in] dbusBootProgress The boot progress in DBUS speak.
756 *
757 * @return Returns as a string, the boot progress in Redfish terms. If
758 * translation cannot be done, returns "None".
759 */
760inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
761{
762 // Now convert the D-Bus BootProgress to the appropriate Redfish
763 // enum
764 std::string rfBpLastState = "None";
765 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
766 "ProgressStages.Unspecified")
767 {
768 rfBpLastState = "None";
769 }
770 else if (dbusBootProgress ==
771 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
772 "PrimaryProcInit")
773 {
774 rfBpLastState = "PrimaryProcessorInitializationStarted";
775 }
776 else if (dbusBootProgress ==
777 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
778 "BusInit")
779 {
780 rfBpLastState = "BusInitializationStarted";
781 }
782 else if (dbusBootProgress ==
783 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
784 "MemoryInit")
785 {
786 rfBpLastState = "MemoryInitializationStarted";
787 }
788 else if (dbusBootProgress ==
789 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
790 "SecondaryProcInit")
791 {
792 rfBpLastState = "SecondaryProcessorInitializationStarted";
793 }
794 else if (dbusBootProgress ==
795 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
796 "PCIInit")
797 {
798 rfBpLastState = "PCIResourceConfigStarted";
799 }
800 else if (dbusBootProgress ==
801 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
802 "SystemSetup")
803 {
804 rfBpLastState = "SetupEntered";
805 }
806 else if (dbusBootProgress ==
807 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
808 "SystemInitComplete")
809 {
810 rfBpLastState = "SystemHardwareInitializationComplete";
811 }
812 else if (dbusBootProgress ==
813 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
814 "OSStart")
815 {
816 rfBpLastState = "OSBootStarted";
817 }
818 else if (dbusBootProgress ==
819 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
820 "OSRunning")
821 {
822 rfBpLastState = "OSRunning";
823 }
824 else
825 {
Ed Tanous62598e32023-07-17 17:06:25 -0700826 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600827 // Just return the default
828 }
829 return rfBpLastState;
830}
831
832/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500833 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530834 *
835 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700836 * @param[out] bootSource The DBus source
837 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700839 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530840 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700841inline int
842 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
843 const std::string& rfSource, std::string& bootSource,
844 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530845{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300846 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
847 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700848
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530849 if (rfSource == "None")
850 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700851 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530852 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700853 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530854 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700855 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
856 }
857 else if (rfSource == "Hdd")
858 {
859 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
860 }
861 else if (rfSource == "Diags")
862 {
863 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
864 }
865 else if (rfSource == "Cd")
866 {
867 bootSource =
868 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
869 }
870 else if (rfSource == "BiosSetup")
871 {
872 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530873 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700874 else if (rfSource == "Usb")
875 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700876 bootSource =
877 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700878 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530879 else
880 {
Ed Tanous62598e32023-07-17 17:06:25 -0700881 BMCWEB_LOG_DEBUG(
882 "Invalid property value for BootSourceOverrideTarget: {}",
883 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700884 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700885 "BootSourceTargetOverride");
886 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530887 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700888 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530889}
Ali Ahmed19817712021-06-29 17:01:52 -0500890
Andrew Geissler978b8802020-11-19 13:36:40 -0600891/**
892 * @brief Retrieves boot progress of the system
893 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700894 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600895 *
896 * @return None.
897 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700898inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600899{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700900 sdbusplus::asio::getProperty<std::string>(
901 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
902 "/xyz/openbmc_project/state/host0",
903 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700904 [asyncResp](const boost::system::error_code& ec,
905 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700906 if (ec)
907 {
908 // BootProgress is an optional object so just do nothing if
909 // not found
910 return;
911 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600912
Ed Tanous62598e32023-07-17 17:06:25 -0700913 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600914
Ed Tanousac106bf2023-06-07 09:24:59 -0700915 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700916 dbusToRfBootProgress(bootProgressStr);
Patrick Williams5a39f772023-10-20 11:20:21 -0500917 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600918}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530919
920/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000921 * @brief Retrieves boot progress Last Update of the system
922 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700923 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000924 *
925 * @return None.
926 */
927inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700928 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000929{
930 sdbusplus::asio::getProperty<uint64_t>(
931 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
932 "/xyz/openbmc_project/state/host0",
933 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700934 [asyncResp](const boost::system::error_code& ec,
935 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000936 if (ec)
937 {
Ed Tanous62598e32023-07-17 17:06:25 -0700938 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000939 return;
940 }
941
942 // BootProgressLastUpdate is the last time the BootProgress property
943 // was updated. The time is the Epoch time, number of microseconds
944 // since 1 Jan 1970 00::00::00 UTC."
945 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
946 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
947
948 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700949 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000950 redfish::time_utils::getDateTimeUintUs(lastStateTime);
Patrick Williams5a39f772023-10-20 11:20:21 -0500951 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000952}
953
954/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300955 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300956 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700957 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300958 *
959 * @return None.
960 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300961
Ed Tanousac106bf2023-06-07 09:24:59 -0700962inline void
963 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300964{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700965 sdbusplus::asio::getProperty<std::string>(
966 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
967 "/xyz/openbmc_project/control/host0/boot",
968 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700969 [asyncResp](const boost::system::error_code& ec,
970 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700971 if (ec)
972 {
973 // not an error, don't have to have the interface
974 return;
975 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300976
Ed Tanous62598e32023-07-17 17:06:25 -0700977 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300978
Ed Tanousac106bf2023-06-07 09:24:59 -0700979 asyncResp->res
980 .jsonValue["Boot"]
981 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700982 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300983
Ed Tanous002d39b2022-05-31 08:59:27 -0700984 auto rfType = dbusToRfBootType(bootType);
985 if (rfType.empty())
986 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700987 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700988 return;
989 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300990
Ed Tanousac106bf2023-06-07 09:24:59 -0700991 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Patrick Williams5a39f772023-10-20 11:20:21 -0500992 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300993}
994
995/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300996 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530997 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700998 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530999 *
1000 * @return None.
1001 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001002
Ed Tanousac106bf2023-06-07 09:24:59 -07001003inline void
1004 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301005{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001006 sdbusplus::asio::getProperty<std::string>(
1007 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1008 "/xyz/openbmc_project/control/host0/boot",
1009 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001010 [asyncResp](const boost::system::error_code& ec,
1011 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001012 if (ec)
1013 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001014 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001015 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001016 return;
1017 }
1018
Ed Tanous62598e32023-07-17 17:06:25 -07001019 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -07001020
Ed Tanousac106bf2023-06-07 09:24:59 -07001021 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001022 .jsonValue["Boot"]
1023 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1024 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1025
1026 if (bootModeStr !=
1027 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1028 {
1029 auto rfMode = dbusToRfBootMode(bootModeStr);
1030 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301031 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001032 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001033 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301034 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001035 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001036 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301037}
1038
1039/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001040 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301041 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001042 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301043 *
1044 * @return None.
1045 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001046
1047inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001048 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301049{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001050 sdbusplus::asio::getProperty<std::string>(
1051 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1052 "/xyz/openbmc_project/control/host0/boot",
1053 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001054 [asyncResp](const boost::system::error_code& ec,
1055 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001056 if (ec)
1057 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001058 if (ec.value() == boost::asio::error::host_unreachable)
1059 {
1060 return;
1061 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001062 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001063 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001064 return;
1065 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301066
Ed Tanous62598e32023-07-17 17:06:25 -07001067 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301068
Ed Tanous002d39b2022-05-31 08:59:27 -07001069 auto rfSource = dbusToRfBootSource(bootSourceStr);
1070 if (!rfSource.empty())
1071 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001072 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1073 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001074 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001075
Ed Tanous002d39b2022-05-31 08:59:27 -07001076 // Get BootMode as BootSourceOverrideTarget is constructed
1077 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001078 getBootOverrideMode(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001079 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301080}
1081
1082/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001083 * @brief This functions abstracts all the logic behind getting a
1084 * "BootSourceOverrideEnabled" property from an overall boot override enable
1085 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301086 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001087 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301088 *
1089 * @return None.
1090 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301091
Ed Tanousac106bf2023-06-07 09:24:59 -07001092inline void processBootOverrideEnable(
1093 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1094 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001095{
1096 if (!bootOverrideEnableSetting)
1097 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001098 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1099 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001100 return;
1101 }
1102
1103 // If boot source override is enabled, we need to check 'one_time'
1104 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001105 sdbusplus::asio::getProperty<bool>(
1106 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1107 "/xyz/openbmc_project/control/host0/boot/one_time",
1108 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001109 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001110 if (ec)
1111 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001112 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001113 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001114 return;
1115 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301116
Ed Tanous002d39b2022-05-31 08:59:27 -07001117 if (oneTimeSetting)
1118 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001119 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1120 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001121 }
1122 else
1123 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001124 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001125 "Continuous";
1126 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001127 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301128}
1129
1130/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001131 * @brief Retrieves boot override enable over DBUS
1132 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001133 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001134 *
1135 * @return None.
1136 */
1137
1138inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001139 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001140{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001141 sdbusplus::asio::getProperty<bool>(
1142 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1143 "/xyz/openbmc_project/control/host0/boot",
1144 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001145 [asyncResp](const boost::system::error_code& ec,
1146 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001147 if (ec)
1148 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001149 if (ec.value() == boost::asio::error::host_unreachable)
1150 {
1151 return;
1152 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001153 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001154 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001155 return;
1156 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001157
Ed Tanousac106bf2023-06-07 09:24:59 -07001158 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Patrick Williams5a39f772023-10-20 11:20:21 -05001159 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001160}
1161
1162/**
1163 * @brief Retrieves boot source override properties
1164 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001165 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001166 *
1167 * @return None.
1168 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001169inline void
1170 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001171{
Ed Tanous62598e32023-07-17 17:06:25 -07001172 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001173
Ed Tanousac106bf2023-06-07 09:24:59 -07001174 getBootOverrideSource(asyncResp);
1175 getBootOverrideType(asyncResp);
1176 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001177}
1178
1179/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001180 * @brief Retrieves the Last Reset Time
1181 *
1182 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1183 * and power off. Even though this is the "system" Redfish object look at the
1184 * chassis D-Bus interface for the LastStateChangeTime since this has the
1185 * last power operation time.
1186 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001187 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001188 *
1189 * @return None.
1190 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001191inline void
1192 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001193{
Ed Tanous62598e32023-07-17 17:06:25 -07001194 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001195
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001196 sdbusplus::asio::getProperty<uint64_t>(
1197 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1198 "/xyz/openbmc_project/state/chassis0",
1199 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001200 [asyncResp](const boost::system::error_code& ec,
1201 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001202 if (ec)
1203 {
Ed Tanous62598e32023-07-17 17:06:25 -07001204 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001205 return;
1206 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001207
Ed Tanous002d39b2022-05-31 08:59:27 -07001208 // LastStateChangeTime is epoch time, in milliseconds
1209 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1210 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001211
Ed Tanous002d39b2022-05-31 08:59:27 -07001212 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001213 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001214 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001215 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001216}
1217
1218/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001219 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1220 *
1221 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1222 * corresponding property "AttemptsLeft" that keeps track of the amount of
1223 * automatic retry attempts left are hosted in phosphor-state-manager through
1224 * dbus.
1225 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001226 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001227 *
1228 * @return None.
1229 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001230inline void getAutomaticRebootAttempts(
1231 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001232{
Ed Tanous62598e32023-07-17 17:06:25 -07001233 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001234
1235 sdbusplus::asio::getAllProperties(
1236 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1237 "/xyz/openbmc_project/state/host0",
1238 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001239 [asyncResp{asyncResp}](
1240 const boost::system::error_code& ec,
1241 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001242 if (ec)
1243 {
1244 if (ec.value() != EBADR)
1245 {
Ed Tanous62598e32023-07-17 17:06:25 -07001246 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001247 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001248 }
1249 return;
1250 }
1251
1252 const uint32_t* attemptsLeft = nullptr;
1253 const uint32_t* retryAttempts = nullptr;
1254
1255 const bool success = sdbusplus::unpackPropertiesNoThrow(
1256 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1257 attemptsLeft, "RetryAttempts", retryAttempts);
1258
1259 if (!success)
1260 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001261 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001262 return;
1263 }
1264
1265 if (attemptsLeft != nullptr)
1266 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001267 asyncResp->res
1268 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001269 *attemptsLeft;
1270 }
1271
1272 if (retryAttempts != nullptr)
1273 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001274 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001275 *retryAttempts;
1276 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001277 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001278}
1279
1280/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001281 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1282 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001283 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001284 *
1285 * @return None.
1286 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001287inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001288 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001289{
Ed Tanous62598e32023-07-17 17:06:25 -07001290 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001291
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001292 sdbusplus::asio::getProperty<bool>(
1293 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1294 "/xyz/openbmc_project/control/host0/auto_reboot",
1295 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001296 [asyncResp](const boost::system::error_code& ec,
1297 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001298 if (ec)
1299 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001300 if (ec.value() != EBADR)
1301 {
Ed Tanous62598e32023-07-17 17:06:25 -07001302 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001303 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001304 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001305 return;
1306 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001307
Ed Tanous62598e32023-07-17 17:06:25 -07001308 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001309 if (autoRebootEnabled)
1310 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001311 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001312 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001313 }
1314 else
1315 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001316 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1317 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001318 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001319 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001320
Ed Tanous002d39b2022-05-31 08:59:27 -07001321 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1322 // and RetryAttempts. OpenBMC only supports Disabled and
1323 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001324 asyncResp->res
1325 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1326 {"Disabled", "RetryAttempts"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001327 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001328}
1329
1330/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001331 * @brief Sets RetryAttempts
1332 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001333 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001334 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1335 *
1336 *@return None.
1337 */
1338
Ed Tanousac106bf2023-06-07 09:24:59 -07001339inline void setAutomaticRetryAttempts(
1340 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1341 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001342{
Ed Tanous62598e32023-07-17 17:06:25 -07001343 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001344 sdbusplus::asio::setProperty(
1345 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1346 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001347 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001348 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001349 if (ec)
1350 {
1351 BMCWEB_LOG_ERROR(
1352 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1353 messages::internalError(asyncResp->res);
1354 return;
1355 }
1356 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001357}
1358
Ed Tanous8d69c662023-06-21 10:29:06 -07001359inline computer_system::PowerRestorePolicyTypes
1360 redfishPowerRestorePolicyFromDbus(std::string_view value)
1361{
1362 if (value ==
1363 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1364 {
1365 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1366 }
1367 if (value ==
1368 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1369 {
1370 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1371 }
1372 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001373 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001374 {
1375 return computer_system::PowerRestorePolicyTypes::LastState;
1376 }
1377 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1378 {
1379 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1380 }
1381 return computer_system::PowerRestorePolicyTypes::Invalid;
1382}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001383/**
George Liuc6a620f2020-04-10 17:18:11 +08001384 * @brief Retrieves power restore policy over DBUS.
1385 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001386 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001387 *
1388 * @return None.
1389 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001390inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001391 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001392{
Ed Tanous62598e32023-07-17 17:06:25 -07001393 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001394
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001395 sdbusplus::asio::getProperty<std::string>(
1396 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1397 "/xyz/openbmc_project/control/host0/power_restore_policy",
1398 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001399 [asyncResp](const boost::system::error_code& ec,
1400 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001401 if (ec)
1402 {
Ed Tanous62598e32023-07-17 17:06:25 -07001403 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001404 return;
1405 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001406 computer_system::PowerRestorePolicyTypes restore =
1407 redfishPowerRestorePolicyFromDbus(policy);
1408 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001409 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001410 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001411 return;
1412 }
George Liuc6a620f2020-04-10 17:18:11 +08001413
Ed Tanous8d69c662023-06-21 10:29:06 -07001414 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Patrick Williams5a39f772023-10-20 11:20:21 -05001415 });
George Liuc6a620f2020-04-10 17:18:11 +08001416}
1417
1418/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001419 * @brief Stop Boot On Fault over DBUS.
1420 *
1421 * @param[in] asyncResp Shared pointer for generating response message.
1422 *
1423 * @return None.
1424 */
1425inline void
1426 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1427{
Ed Tanous62598e32023-07-17 17:06:25 -07001428 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001429
1430 sdbusplus::asio::getProperty<bool>(
1431 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1432 "/xyz/openbmc_project/logging/settings",
1433 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1434 [asyncResp](const boost::system::error_code& ec, bool value) {
1435 if (ec)
1436 {
1437 if (ec.value() != EBADR)
1438 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001439 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001440 messages::internalError(asyncResp->res);
1441 }
1442 return;
1443 }
1444
1445 if (value)
1446 {
1447 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1448 }
1449 else
1450 {
1451 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1452 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001453 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001454}
1455
1456/**
Ali Ahmed19817712021-06-29 17:01:52 -05001457 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1458 * TPM is required for booting the host.
1459 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001460 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001461 *
1462 * @return None.
1463 */
1464inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001465 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001466{
Ed Tanous62598e32023-07-17 17:06:25 -07001467 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001468 constexpr std::array<std::string_view, 1> interfaces = {
1469 "xyz.openbmc_project.Control.TPM.Policy"};
1470 dbus::utility::getSubTree(
1471 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001472 [asyncResp](const boost::system::error_code& ec,
1473 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001474 if (ec)
1475 {
Ed Tanous62598e32023-07-17 17:06:25 -07001476 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1477 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001478 // This is an optional D-Bus object so just return if
1479 // error occurs
1480 return;
1481 }
1482 if (subtree.empty())
1483 {
1484 // As noted above, this is an optional interface so just return
1485 // if there is no instance found
1486 return;
1487 }
1488
1489 /* When there is more than one TPMEnable object... */
1490 if (subtree.size() > 1)
1491 {
Ed Tanous62598e32023-07-17 17:06:25 -07001492 BMCWEB_LOG_DEBUG(
1493 "DBUS response has more than 1 TPM Enable object:{}",
1494 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001495 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001496 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001497 return;
1498 }
1499
1500 // Make sure the Dbus response map has a service and objectPath
1501 // field
1502 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1503 {
Ed Tanous62598e32023-07-17 17:06:25 -07001504 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001505 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001506 return;
1507 }
1508
1509 const std::string& path = subtree[0].first;
1510 const std::string& serv = subtree[0].second.begin()->first;
1511
1512 // Valid TPM Enable object found, now reading the current value
1513 sdbusplus::asio::getProperty<bool>(
1514 *crow::connections::systemBus, serv, path,
1515 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001516 [asyncResp](const boost::system::error_code& ec2,
1517 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001518 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001519 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001520 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001521 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001522 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001523 return;
1524 }
1525
Ed Tanous002d39b2022-05-31 08:59:27 -07001526 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001527 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001528 asyncResp->res
1529 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001530 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001531 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001532 else
1533 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001534 asyncResp->res
1535 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001536 "Disabled";
1537 }
George Liue99073f2022-12-09 11:06:16 +08001538 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001539 });
Ali Ahmed19817712021-06-29 17:01:52 -05001540}
1541
1542/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001543 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1544 * TPM is required for booting the host.
1545 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001546 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001547 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1548 *
1549 * @return None.
1550 */
1551inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001552 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001553{
Ed Tanous62598e32023-07-17 17:06:25 -07001554 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001555 constexpr std::array<std::string_view, 1> interfaces = {
1556 "xyz.openbmc_project.Control.TPM.Policy"};
1557 dbus::utility::getSubTree(
1558 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001559 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001560 tpmRequired](const boost::system::error_code& ec,
1561 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001562 if (ec)
1563 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001564 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001565 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001566 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001567 return;
1568 }
1569 if (subtree.empty())
1570 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001571 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001572 "TrustedModuleRequiredToBoot");
1573 return;
1574 }
1575
1576 /* When there is more than one TPMEnable object... */
1577 if (subtree.size() > 1)
1578 {
Ed Tanous62598e32023-07-17 17:06:25 -07001579 BMCWEB_LOG_DEBUG(
1580 "DBUS response has more than 1 TPM Enable object:{}",
1581 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001582 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001583 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001584 return;
1585 }
1586
1587 // Make sure the Dbus response map has a service and objectPath
1588 // field
1589 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1590 {
Ed Tanous62598e32023-07-17 17:06:25 -07001591 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001592 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001593 return;
1594 }
1595
1596 const std::string& path = subtree[0].first;
1597 const std::string& serv = subtree[0].second.begin()->first;
1598
1599 if (serv.empty())
1600 {
Ed Tanous62598e32023-07-17 17:06:25 -07001601 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001602 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001603 return;
1604 }
1605
1606 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001607 sdbusplus::asio::setProperty(
1608 *crow::connections::systemBus, serv, path,
1609 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001610 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001611 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001612 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001613 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001614 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1615 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001616 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001617 return;
1618 }
Ed Tanous62598e32023-07-17 17:06:25 -07001619 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001620 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001621 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001622}
1623
1624/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301625 * @brief Sets boot properties into DBUS object(s).
1626 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001627 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001628 * @param[in] bootType The boot type to set.
1629 * @return Integer error code.
1630 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001631inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001632 const std::optional<std::string>& bootType)
1633{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001634 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001635
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001636 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001637 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001638 return;
1639 }
1640
1641 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001642 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001643 // Figure out which DBUS interface and property to use
1644 if (*bootType == "Legacy")
1645 {
1646 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1647 }
1648 else if (*bootType == "UEFI")
1649 {
1650 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1651 }
1652 else
1653 {
Ed Tanous62598e32023-07-17 17:06:25 -07001654 BMCWEB_LOG_DEBUG("Invalid property value for "
1655 "BootSourceOverrideMode: {}",
1656 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001657 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001658 "BootSourceOverrideMode");
1659 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001660 }
1661
1662 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001663 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001664
George Liu9ae226f2023-06-21 17:56:46 +08001665 sdbusplus::asio::setProperty(
1666 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1667 "/xyz/openbmc_project/control/host0/boot",
1668 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001669 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001670 if (ec)
1671 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001672 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001673 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001674 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001675 return;
1676 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001677 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001678 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001679 return;
1680 }
Ed Tanous62598e32023-07-17 17:06:25 -07001681 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001682 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001683}
1684
1685/**
1686 * @brief Sets boot properties into DBUS object(s).
1687 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001688 * @param[in] asyncResp Shared pointer for generating response
1689 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001690 * @param[in] bootType The boot type to set.
1691 * @return Integer error code.
1692 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001693inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001694 const std::optional<std::string>& bootEnable)
1695{
1696 if (!bootEnable)
1697 {
1698 return;
1699 }
1700 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001701 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001702
1703 bool bootOverrideEnable = false;
1704 bool bootOverridePersistent = false;
1705 // Figure out which DBUS interface and property to use
1706 if (*bootEnable == "Disabled")
1707 {
1708 bootOverrideEnable = false;
1709 }
1710 else if (*bootEnable == "Once")
1711 {
1712 bootOverrideEnable = true;
1713 bootOverridePersistent = false;
1714 }
1715 else if (*bootEnable == "Continuous")
1716 {
1717 bootOverrideEnable = true;
1718 bootOverridePersistent = true;
1719 }
1720 else
1721 {
Ed Tanous62598e32023-07-17 17:06:25 -07001722 BMCWEB_LOG_DEBUG(
1723 "Invalid property value for BootSourceOverrideEnabled: {}",
1724 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001725 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001726 "BootSourceOverrideEnabled");
1727 return;
1728 }
1729
1730 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001731 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001732
George Liu9ae226f2023-06-21 17:56:46 +08001733 sdbusplus::asio::setProperty(
1734 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1735 "/xyz/openbmc_project/control/host0/boot",
1736 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001737 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001738 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001739 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001740 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001741 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001742 return;
1743 }
Ed Tanous62598e32023-07-17 17:06:25 -07001744 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001745 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001746
1747 if (!bootOverrideEnable)
1748 {
1749 return;
1750 }
1751
1752 // In case boot override is enabled we need to set correct value for the
1753 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001754 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1755 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001756
George Liu9ae226f2023-06-21 17:56:46 +08001757 sdbusplus::asio::setProperty(
1758 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1759 "/xyz/openbmc_project/control/host0/boot/one_time",
1760 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001761 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001762 if (ec)
1763 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001764 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001765 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001766 return;
1767 }
Ed Tanous62598e32023-07-17 17:06:25 -07001768 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001769 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001770}
1771
1772/**
1773 * @brief Sets boot properties into DBUS object(s).
1774 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001775 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301776 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301777 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001778 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301779 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001780inline void
1781 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1782 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301783{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001784 std::string bootSourceStr;
1785 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001786
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001787 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301788 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001789 return;
1790 }
1791
1792 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001793 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001794 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001795 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1796 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001797 {
Ed Tanous62598e32023-07-17 17:06:25 -07001798 BMCWEB_LOG_DEBUG(
1799 "Invalid property value for BootSourceOverrideTarget: {}",
1800 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001801 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001802 "BootSourceTargetOverride");
1803 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001804 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301805
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001806 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001807 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1808 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001809
George Liu9ae226f2023-06-21 17:56:46 +08001810 sdbusplus::asio::setProperty(
1811 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1812 "/xyz/openbmc_project/control/host0/boot",
1813 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001814 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001815 if (ec)
1816 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001817 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001818 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001819 return;
1820 }
Ed Tanous62598e32023-07-17 17:06:25 -07001821 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001822 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001823
George Liu9ae226f2023-06-21 17:56:46 +08001824 sdbusplus::asio::setProperty(
1825 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1826 "/xyz/openbmc_project/control/host0/boot",
1827 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001828 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001829 if (ec)
1830 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001831 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001832 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001833 return;
1834 }
Ed Tanous62598e32023-07-17 17:06:25 -07001835 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001836 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001837}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001838
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001839/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001840 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301841 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001842 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301843 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001844 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301845 * @param[in] bootEnable The boot override enable from incoming RF request.
1846 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001847 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301848 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001849
Ed Tanousac106bf2023-06-07 09:24:59 -07001850inline void
1851 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1852 const std::optional<std::string>& bootSource,
1853 const std::optional<std::string>& bootType,
1854 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301855{
Ed Tanous62598e32023-07-17 17:06:25 -07001856 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301857
Ed Tanousac106bf2023-06-07 09:24:59 -07001858 setBootModeOrSource(asyncResp, bootSource);
1859 setBootType(asyncResp, bootType);
1860 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301861}
1862
George Liuc6a620f2020-04-10 17:18:11 +08001863/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001864 * @brief Sets AssetTag
1865 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001866 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001867 * @param[in] assetTag "AssetTag" from request.
1868 *
1869 * @return None.
1870 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001871inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001872 const std::string& assetTag)
1873{
George Liue99073f2022-12-09 11:06:16 +08001874 constexpr std::array<std::string_view, 1> interfaces = {
1875 "xyz.openbmc_project.Inventory.Item.System"};
1876 dbus::utility::getSubTree(
1877 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001878 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001879 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001880 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001881 if (ec)
1882 {
Ed Tanous62598e32023-07-17 17:06:25 -07001883 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001884 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001885 return;
1886 }
1887 if (subtree.empty())
1888 {
Ed Tanous62598e32023-07-17 17:06:25 -07001889 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001890 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001891 return;
1892 }
1893 // Assume only 1 system D-Bus object
1894 // Throw an error if there is more than 1
1895 if (subtree.size() > 1)
1896 {
Ed Tanous62598e32023-07-17 17:06:25 -07001897 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001898 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001899 return;
1900 }
1901 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1902 {
Ed Tanous62598e32023-07-17 17:06:25 -07001903 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001904 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001905 return;
1906 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001907
Ed Tanous002d39b2022-05-31 08:59:27 -07001908 const std::string& path = subtree[0].first;
1909 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001910
Ed Tanous002d39b2022-05-31 08:59:27 -07001911 if (service.empty())
1912 {
Ed Tanous62598e32023-07-17 17:06:25 -07001913 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001914 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001915 return;
1916 }
1917
George Liu9ae226f2023-06-21 17:56:46 +08001918 sdbusplus::asio::setProperty(
1919 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001920 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001921 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001922 if (ec2)
1923 {
1924 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1925 ec2);
1926 messages::internalError(asyncResp->res);
1927 return;
1928 }
George Liue99073f2022-12-09 11:06:16 +08001929 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001930 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001931}
1932
1933/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001934 * @brief Validate the specified stopBootOnFault is valid and return the
1935 * stopBootOnFault name associated with that string
1936 *
1937 * @param[in] stopBootOnFaultString String representing the desired
1938 * stopBootOnFault
1939 *
1940 * @return stopBootOnFault value or empty if incoming value is not valid
1941 */
1942inline std::optional<bool>
1943 validstopBootOnFault(const std::string& stopBootOnFaultString)
1944{
1945 if (stopBootOnFaultString == "AnyFault")
1946 {
1947 return true;
1948 }
1949
1950 if (stopBootOnFaultString == "Never")
1951 {
1952 return false;
1953 }
1954
1955 return std::nullopt;
1956}
1957
1958/**
1959 * @brief Sets stopBootOnFault
1960 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001961 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001962 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1963 *
1964 * @return None.
1965 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001966inline void
1967 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1968 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001969{
Ed Tanous62598e32023-07-17 17:06:25 -07001970 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001971
1972 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1973 if (!stopBootEnabled)
1974 {
Ed Tanous62598e32023-07-17 17:06:25 -07001975 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1976 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001977 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001978 "StopBootOnFault");
1979 return;
1980 }
1981
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001982 sdbusplus::asio::setProperty(
1983 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1984 "/xyz/openbmc_project/logging/settings",
1985 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1986 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001987 if (ec)
1988 {
1989 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001990 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001991 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1992 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001993 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001994 return;
1995 }
1996 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001997}
1998
1999/**
Gunnar Mills69f35302020-05-17 16:06:31 -05002000 * @brief Sets automaticRetry (Auto Reboot)
2001 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002002 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05002003 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
2004 *
2005 * @return None.
2006 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002007inline void
2008 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2009 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05002010{
Ed Tanous62598e32023-07-17 17:06:25 -07002011 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05002012
2013 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002014 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002015
2016 if (automaticRetryConfig == "Disabled")
2017 {
2018 autoRebootEnabled = false;
2019 }
2020 else if (automaticRetryConfig == "RetryAttempts")
2021 {
2022 autoRebootEnabled = true;
2023 }
2024 else
2025 {
Ed Tanous62598e32023-07-17 17:06:25 -07002026 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
2027 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07002028 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002029 "AutomaticRetryConfig");
2030 return;
2031 }
2032
George Liu9ae226f2023-06-21 17:56:46 +08002033 sdbusplus::asio::setProperty(
2034 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002035 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002036 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002037 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002038 if (ec)
2039 {
2040 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2041 messages::internalError(asyncResp->res);
2042 return;
2043 }
2044 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002045}
2046
Ed Tanous8d69c662023-06-21 10:29:06 -07002047inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2048{
2049 if (policy == "AlwaysOn")
2050 {
2051 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2052 }
2053 if (policy == "AlwaysOff")
2054 {
2055 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2056 }
2057 if (policy == "LastState")
2058 {
2059 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2060 }
2061 return "";
2062}
2063
Gunnar Mills69f35302020-05-17 16:06:31 -05002064/**
George Liuc6a620f2020-04-10 17:18:11 +08002065 * @brief Sets power restore policy properties.
2066 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002067 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002068 * @param[in] policy power restore policy properties from request.
2069 *
2070 * @return None.
2071 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002072inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002073 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002074 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002075{
Ed Tanous62598e32023-07-17 17:06:25 -07002076 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002077
Ed Tanous8d69c662023-06-21 10:29:06 -07002078 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002079
Ed Tanous8d69c662023-06-21 10:29:06 -07002080 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002081 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002082 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002083 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002084 return;
2085 }
2086
George Liu9ae226f2023-06-21 17:56:46 +08002087 sdbusplus::asio::setProperty(
2088 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002089 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002090 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002091 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002092 if (ec)
2093 {
2094 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2095 messages::internalError(asyncResp->res);
2096 return;
2097 }
2098 });
George Liuc6a620f2020-04-10 17:18:11 +08002099}
2100
AppaRao Pulia6349912019-10-18 17:16:08 +05302101#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2102/**
2103 * @brief Retrieves provisioning status
2104 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002105 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302106 *
2107 * @return None.
2108 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002109inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302110{
Ed Tanous62598e32023-07-17 17:06:25 -07002111 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002112 sdbusplus::asio::getAllProperties(
2113 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2114 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002115 [asyncResp](const boost::system::error_code& ec,
2116 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002117 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002118 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2119 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002120 "#OemComputerSystem.OpenBmc";
2121 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002122
Ed Tanous002d39b2022-05-31 08:59:27 -07002123 if (ec)
2124 {
Ed Tanous62598e32023-07-17 17:06:25 -07002125 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002126 // not an error, don't have to have the interface
2127 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2128 return;
2129 }
2130
2131 const bool* provState = nullptr;
2132 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002133
2134 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002135 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2136 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002137
2138 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002139 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002140 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002141 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002142 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302143
Ed Tanous002d39b2022-05-31 08:59:27 -07002144 if ((provState == nullptr) || (lockState == nullptr))
2145 {
Ed Tanous62598e32023-07-17 17:06:25 -07002146 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002147 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002148 return;
2149 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302150
Ed Tanous002d39b2022-05-31 08:59:27 -07002151 if (*provState == true)
2152 {
2153 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302154 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002155 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302156 }
2157 else
2158 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002159 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302160 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002161 }
2162 else
2163 {
2164 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2165 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002166 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302167}
2168#endif
2169
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302170/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002171 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002172 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002173 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002174 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002175 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002176 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002177inline computer_system::PowerMode
2178 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002179{
Chris Cainb6655102024-02-01 14:35:33 -06002180 using PowerMode = computer_system::PowerMode;
2181
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002182 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002183 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002184 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002185 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002186 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002187 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002188 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002189 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002190 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002191 if (modeString ==
2192 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002193 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002194 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002195 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002196 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002197 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2198 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002199 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002200 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002201 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002202 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2203 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002204 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002205 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002206 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002207 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2208 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002209 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002210 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002211 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002212 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002213 return PowerMode::OEM;
2214 }
2215 // Any other values would be invalid
2216 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2217 return PowerMode::Invalid;
2218}
2219
2220inline void
2221 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2222 const boost::system::error_code& ec,
2223 const dbus::utility::DBusPropertiesMap& properties)
2224{
2225 if (ec)
2226 {
2227 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2228 messages::internalError(asyncResp->res);
2229 return;
2230 }
2231
2232 std::string powerMode;
2233 const std::vector<std::string>* allowedModes = nullptr;
2234 const bool success = sdbusplus::unpackPropertiesNoThrow(
2235 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2236 "AllowedPowerModes", allowedModes);
2237
2238 if (!success)
2239 {
2240 messages::internalError(asyncResp->res);
2241 return;
2242 }
2243
2244 nlohmann::json::array_t modeList;
2245 if (allowedModes == nullptr)
2246 {
2247 modeList.emplace_back("Static");
2248 modeList.emplace_back("MaximumPerformance");
2249 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002250 }
2251 else
2252 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002253 for (const auto& aMode : *allowedModes)
2254 {
2255 computer_system::PowerMode modeValue =
2256 translatePowerModeString(aMode);
2257 if (modeValue == computer_system::PowerMode::Invalid)
2258 {
2259 messages::internalError(asyncResp->res);
2260 continue;
2261 }
2262 modeList.emplace_back(modeValue);
2263 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002264 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002265 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002266
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002267 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2268 const computer_system::PowerMode modeValue =
2269 translatePowerModeString(powerMode);
2270 if (modeValue == computer_system::PowerMode::Invalid)
2271 {
2272 messages::internalError(asyncResp->res);
2273 return;
2274 }
2275 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2276}
Chris Cain3a2d04242021-05-28 16:57:10 -05002277/**
2278 * @brief Retrieves system power mode
2279 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002280 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002281 *
2282 * @return None.
2283 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002284inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002285{
Ed Tanous62598e32023-07-17 17:06:25 -07002286 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002287
2288 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002289 constexpr std::array<std::string_view, 1> interfaces = {
2290 "xyz.openbmc_project.Control.Power.Mode"};
2291 dbus::utility::getSubTree(
2292 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002293 [asyncResp](const boost::system::error_code& ec,
2294 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002295 if (ec)
2296 {
Ed Tanous62598e32023-07-17 17:06:25 -07002297 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2298 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002299 // This is an optional D-Bus object so just return if
2300 // error occurs
2301 return;
2302 }
2303 if (subtree.empty())
2304 {
2305 // As noted above, this is an optional interface so just return
2306 // if there is no instance found
2307 return;
2308 }
2309 if (subtree.size() > 1)
2310 {
2311 // More then one PowerMode object is not supported and is an
2312 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002313 BMCWEB_LOG_DEBUG(
2314 "Found more than 1 system D-Bus Power.Mode objects: {}",
2315 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002316 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002317 return;
2318 }
2319 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2320 {
Ed Tanous62598e32023-07-17 17:06:25 -07002321 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002322 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002323 return;
2324 }
2325 const std::string& path = subtree[0].first;
2326 const std::string& service = subtree[0].second.begin()->first;
2327 if (service.empty())
2328 {
Ed Tanous62598e32023-07-17 17:06:25 -07002329 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002330 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002331 return;
2332 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002333
2334 // Valid Power Mode object found, now read the mode properties
2335 sdbusplus::asio::getAllProperties(
Ed Tanous002d39b2022-05-31 08:59:27 -07002336 *crow::connections::systemBus, service, path,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002337 "xyz.openbmc_project.Control.Power.Mode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002338 [asyncResp](const boost::system::error_code& ec2,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002339 const dbus::utility::DBusPropertiesMap& properties) {
2340 afterGetPowerMode(asyncResp, ec2, properties);
George Liue99073f2022-12-09 11:06:16 +08002341 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002342 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002343}
2344
2345/**
2346 * @brief Validate the specified mode is valid and return the PowerMode
2347 * name associated with that string
2348 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002349 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002350 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002351 *
2352 * @return PowerMode value or empty string if mode is not valid
2353 */
2354inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002355 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002356 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002357{
Chris Cainb6655102024-02-01 14:35:33 -06002358 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002359 std::string mode;
2360
Chris Cainb6655102024-02-01 14:35:33 -06002361 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002362 {
2363 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2364 }
Chris Cainb6655102024-02-01 14:35:33 -06002365 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002366 {
George Liu0fda0f12021-11-16 10:06:17 +08002367 mode =
2368 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002369 }
Chris Cainb6655102024-02-01 14:35:33 -06002370 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002371 {
2372 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2373 }
Chris Cainb6655102024-02-01 14:35:33 -06002374 else if (modeValue == PowerMode::BalancedPerformance)
2375 {
2376 mode =
2377 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2378 }
2379 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2380 {
2381 mode =
2382 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2383 }
2384 else if (modeValue == PowerMode::EfficiencyFavorPower)
2385 {
2386 mode =
2387 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2388 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002389 else
2390 {
Chris Cainb6655102024-02-01 14:35:33 -06002391 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002392 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002393 }
2394 return mode;
2395}
2396
2397/**
2398 * @brief Sets system power mode.
2399 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002400 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002401 * @param[in] pmode System power mode from request.
2402 *
2403 * @return None.
2404 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002405inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002406 const std::string& pmode)
2407{
Ed Tanous62598e32023-07-17 17:06:25 -07002408 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002409
Ed Tanousac106bf2023-06-07 09:24:59 -07002410 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002411 if (powerMode.empty())
2412 {
2413 return;
2414 }
2415
2416 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002417 constexpr std::array<std::string_view, 1> interfaces = {
2418 "xyz.openbmc_project.Control.Power.Mode"};
2419 dbus::utility::getSubTree(
2420 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002421 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002422 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002423 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002424 if (ec)
2425 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002426 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002427 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002428 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002429 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002430 return;
2431 }
2432 if (subtree.empty())
2433 {
2434 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002435 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002436 "PowerMode");
2437 return;
2438 }
2439 if (subtree.size() > 1)
2440 {
2441 // More then one PowerMode object is not supported and is an
2442 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002443 BMCWEB_LOG_DEBUG(
2444 "Found more than 1 system D-Bus Power.Mode objects: {}",
2445 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002446 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002447 return;
2448 }
2449 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2450 {
Ed Tanous62598e32023-07-17 17:06:25 -07002451 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002452 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002453 return;
2454 }
2455 const std::string& path = subtree[0].first;
2456 const std::string& service = subtree[0].second.begin()->first;
2457 if (service.empty())
2458 {
Ed Tanous62598e32023-07-17 17:06:25 -07002459 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002460 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002461 return;
2462 }
2463
Ed Tanous62598e32023-07-17 17:06:25 -07002464 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002465
2466 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002467 sdbusplus::asio::setProperty(
2468 *crow::connections::systemBus, service, path,
2469 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002470 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002471 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002472 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002473 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002474 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002475 return;
2476 }
George Liue99073f2022-12-09 11:06:16 +08002477 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002478 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002479}
2480
2481/**
Yong Li51709ff2019-09-30 14:13:04 +08002482 * @brief Translates watchdog timeout action DBUS property value to redfish.
2483 *
2484 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2485 *
2486 * @return Returns as a string, the timeout action in Redfish terms. If
2487 * translation cannot be done, returns an empty string.
2488 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002489inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002490{
2491 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2492 {
2493 return "None";
2494 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002495 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002496 {
2497 return "ResetSystem";
2498 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002499 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002500 {
2501 return "PowerDown";
2502 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002503 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002504 {
2505 return "PowerCycle";
2506 }
2507
2508 return "";
2509}
2510
2511/**
Yong Lic45f0082019-10-10 14:19:01 +08002512 *@brief Translates timeout action from Redfish to DBUS property value.
2513 *
2514 *@param[in] rfAction The timeout action in Redfish.
2515 *
2516 *@return Returns as a string, the time_out action as expected by DBUS.
2517 *If translation cannot be done, returns an empty string.
2518 */
2519
Ed Tanous23a21a12020-07-25 04:45:05 +00002520inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002521{
2522 if (rfAction == "None")
2523 {
2524 return "xyz.openbmc_project.State.Watchdog.Action.None";
2525 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002526 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002527 {
2528 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2529 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002530 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002531 {
2532 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2533 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002534 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002535 {
2536 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2537 }
2538
2539 return "";
2540}
2541
2542/**
Yong Li51709ff2019-09-30 14:13:04 +08002543 * @brief Retrieves host watchdog timer properties over DBUS
2544 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002545 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002546 *
2547 * @return None.
2548 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002549inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002550 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002551{
Ed Tanous62598e32023-07-17 17:06:25 -07002552 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002553 sdbusplus::asio::getAllProperties(
2554 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2555 "/xyz/openbmc_project/watchdog/host0",
2556 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002557 [asyncResp](const boost::system::error_code& ec,
2558 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002559 if (ec)
2560 {
2561 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002562 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002563 return;
2564 }
2565
Ed Tanous62598e32023-07-17 17:06:25 -07002566 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002567
2568 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002569 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002570
2571 // watchdog service is running/enabled
2572 hostWatchdogTimer["Status"]["State"] = "Enabled";
2573
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002574 const bool* enabled = nullptr;
2575 const std::string* expireAction = nullptr;
2576
2577 const bool success = sdbusplus::unpackPropertiesNoThrow(
2578 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2579 "ExpireAction", expireAction);
2580
2581 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002582 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002583 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002584 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002585 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002586
2587 if (enabled != nullptr)
2588 {
2589 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2590 }
2591
2592 if (expireAction != nullptr)
2593 {
2594 std::string action = dbusToRfWatchdogAction(*expireAction);
2595 if (action.empty())
2596 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002597 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002598 return;
2599 }
2600 hostWatchdogTimer["TimeoutAction"] = action;
2601 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002602 });
Yong Li51709ff2019-09-30 14:13:04 +08002603}
2604
2605/**
Yong Lic45f0082019-10-10 14:19:01 +08002606 * @brief Sets Host WatchDog Timer properties.
2607 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002608 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002609 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2610 * RF request.
2611 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2612 *
2613 * @return None.
2614 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002615inline void
2616 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2617 const std::optional<bool> wdtEnable,
2618 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002619{
Ed Tanous62598e32023-07-17 17:06:25 -07002620 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002621
2622 if (wdtTimeOutAction)
2623 {
2624 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2625 // check if TimeOut Action is Valid
2626 if (wdtTimeOutActStr.empty())
2627 {
Ed Tanous62598e32023-07-17 17:06:25 -07002628 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2629 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002630 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002631 "TimeoutAction");
2632 return;
2633 }
2634
George Liu9ae226f2023-06-21 17:56:46 +08002635 sdbusplus::asio::setProperty(
2636 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002637 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002638 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002639 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002640 if (ec)
2641 {
2642 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2643 messages::internalError(asyncResp->res);
2644 return;
2645 }
2646 });
Yong Lic45f0082019-10-10 14:19:01 +08002647 }
2648
2649 if (wdtEnable)
2650 {
George Liu9ae226f2023-06-21 17:56:46 +08002651 sdbusplus::asio::setProperty(
2652 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2653 "/xyz/openbmc_project/watchdog/host0",
2654 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002655 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002656 if (ec)
2657 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002658 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002659 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002660 return;
2661 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002662 });
Yong Lic45f0082019-10-10 14:19:01 +08002663 }
2664}
2665
Chris Cain37bbf982021-09-20 10:53:09 -05002666/**
2667 * @brief Parse the Idle Power Saver properties into json
2668 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002669 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002670 * @param[in] properties IPS property data from DBus.
2671 *
2672 * @return true if successful
2673 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002674inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002675 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002676 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002677{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002678 const bool* enabled = nullptr;
2679 const uint8_t* enterUtilizationPercent = nullptr;
2680 const uint64_t* enterDwellTime = nullptr;
2681 const uint8_t* exitUtilizationPercent = nullptr;
2682 const uint64_t* exitDwellTime = nullptr;
2683
2684 const bool success = sdbusplus::unpackPropertiesNoThrow(
2685 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002686 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2687 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2688 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002689
2690 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002691 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002692 return false;
2693 }
2694
2695 if (enabled != nullptr)
2696 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002697 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002698 }
2699
2700 if (enterUtilizationPercent != nullptr)
2701 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002702 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002703 *enterUtilizationPercent;
2704 }
2705
2706 if (enterDwellTime != nullptr)
2707 {
2708 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002709 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002710 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2711 .count();
2712 }
2713
2714 if (exitUtilizationPercent != nullptr)
2715 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002716 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002717 *exitUtilizationPercent;
2718 }
2719
2720 if (exitDwellTime != nullptr)
2721 {
2722 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002723 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002724 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2725 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002726 }
2727
2728 return true;
2729}
2730
2731/**
2732 * @brief Retrieves host watchdog timer properties over DBUS
2733 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002734 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002735 *
2736 * @return None.
2737 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002738inline void
2739 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002740{
Ed Tanous62598e32023-07-17 17:06:25 -07002741 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002742
2743 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002744 constexpr std::array<std::string_view, 1> interfaces = {
2745 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2746 dbus::utility::getSubTree(
2747 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002748 [asyncResp](const boost::system::error_code& ec,
2749 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002750 if (ec)
2751 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002752 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002753 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2754 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002755 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002756 return;
2757 }
2758 if (subtree.empty())
2759 {
2760 // This is an optional interface so just return
2761 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002762 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002763 return;
2764 }
2765 if (subtree.size() > 1)
2766 {
2767 // More then one PowerIdlePowerSaver object is not supported and
2768 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002769 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2770 "Power.IdlePowerSaver objects: {}",
2771 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002772 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002773 return;
2774 }
2775 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2776 {
Ed Tanous62598e32023-07-17 17:06:25 -07002777 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002778 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002779 return;
2780 }
2781 const std::string& path = subtree[0].first;
2782 const std::string& service = subtree[0].second.begin()->first;
2783 if (service.empty())
2784 {
Ed Tanous62598e32023-07-17 17:06:25 -07002785 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002786 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002787 return;
2788 }
2789
2790 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002791 sdbusplus::asio::getAllProperties(
2792 *crow::connections::systemBus, service, path,
2793 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002794 [asyncResp](const boost::system::error_code& ec2,
2795 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002796 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002797 {
Ed Tanous62598e32023-07-17 17:06:25 -07002798 BMCWEB_LOG_ERROR(
2799 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002800 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002801 return;
2802 }
2803
Ed Tanousac106bf2023-06-07 09:24:59 -07002804 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002805 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002806 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002807 return;
2808 }
George Liue99073f2022-12-09 11:06:16 +08002809 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002810 });
Chris Cain37bbf982021-09-20 10:53:09 -05002811
Ed Tanous62598e32023-07-17 17:06:25 -07002812 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002813}
2814
2815/**
2816 * @brief Sets Idle Power Saver properties.
2817 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002818 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002819 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2820 * RF request.
2821 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2822 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2823 * before entering idle state.
2824 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2825 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2826 * before exiting idle state
2827 *
2828 * @return None.
2829 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002830inline void
2831 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2832 const std::optional<bool> ipsEnable,
2833 const std::optional<uint8_t> ipsEnterUtil,
2834 const std::optional<uint64_t> ipsEnterTime,
2835 const std::optional<uint8_t> ipsExitUtil,
2836 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002837{
Ed Tanous62598e32023-07-17 17:06:25 -07002838 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002839
2840 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002841 constexpr std::array<std::string_view, 1> interfaces = {
2842 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2843 dbus::utility::getSubTree(
2844 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002845 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002846 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002847 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002848 if (ec)
2849 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002850 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002851 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2852 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002853 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002854 return;
2855 }
2856 if (subtree.empty())
2857 {
2858 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002859 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002860 "IdlePowerSaver");
2861 return;
2862 }
2863 if (subtree.size() > 1)
2864 {
2865 // More then one PowerIdlePowerSaver object is not supported and
2866 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002867 BMCWEB_LOG_DEBUG(
2868 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2869 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002870 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002871 return;
2872 }
2873 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2874 {
Ed Tanous62598e32023-07-17 17:06:25 -07002875 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002876 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002877 return;
2878 }
2879 const std::string& path = subtree[0].first;
2880 const std::string& service = subtree[0].second.begin()->first;
2881 if (service.empty())
2882 {
Ed Tanous62598e32023-07-17 17:06:25 -07002883 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002884 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002885 return;
2886 }
Chris Cain37bbf982021-09-20 10:53:09 -05002887
Ed Tanous002d39b2022-05-31 08:59:27 -07002888 // Valid Power IdlePowerSaver object found, now set any values that
2889 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002890
Ed Tanous002d39b2022-05-31 08:59:27 -07002891 if (ipsEnable)
2892 {
George Liu9ae226f2023-06-21 17:56:46 +08002893 sdbusplus::asio::setProperty(
2894 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002895 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002896 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002897 if (ec2)
2898 {
2899 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2900 messages::internalError(asyncResp->res);
2901 return;
2902 }
2903 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002904 }
2905 if (ipsEnterUtil)
2906 {
George Liu9ae226f2023-06-21 17:56:46 +08002907 sdbusplus::asio::setProperty(
2908 *crow::connections::systemBus, service, path,
2909 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2910 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002911 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002912 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002913 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002914 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002915 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002916 return;
2917 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002918 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002919 }
2920 if (ipsEnterTime)
2921 {
2922 // Convert from seconds into milliseconds for DBus
2923 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002924 sdbusplus::asio::setProperty(
2925 *crow::connections::systemBus, service, path,
2926 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2927 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002928 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002929 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002930 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002931 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002932 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002933 return;
2934 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002935 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002936 }
2937 if (ipsExitUtil)
2938 {
George Liu9ae226f2023-06-21 17:56:46 +08002939 sdbusplus::asio::setProperty(
2940 *crow::connections::systemBus, service, path,
2941 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2942 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002943 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002944 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002945 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002946 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002947 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002948 return;
2949 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002950 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002951 }
2952 if (ipsExitTime)
2953 {
2954 // Convert from seconds into milliseconds for DBus
2955 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002956 sdbusplus::asio::setProperty(
2957 *crow::connections::systemBus, service, path,
2958 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2959 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002960 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002961 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002962 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002963 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002964 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002965 return;
2966 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002967 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002968 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002969 });
Chris Cain37bbf982021-09-20 10:53:09 -05002970
Ed Tanous62598e32023-07-17 17:06:25 -07002971 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002972}
2973
Ed Tanousc1e219d2023-06-07 10:34:33 -07002974inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002975 crow::App& app, const crow::Request& req,
2976 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2977{
2978 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2979 {
2980 return;
2981 }
2982 asyncResp->res.addHeader(
2983 boost::beast::http::field::link,
2984 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2985}
2986
Ed Tanousc1e219d2023-06-07 10:34:33 -07002987inline void handleComputerSystemCollectionGet(
2988 crow::App& app, const crow::Request& req,
2989 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2990{
2991 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2992 {
2993 return;
2994 }
2995
2996 asyncResp->res.addHeader(
2997 boost::beast::http::field::link,
2998 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2999 asyncResp->res.jsonValue["@odata.type"] =
3000 "#ComputerSystemCollection.ComputerSystemCollection";
3001 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
3002 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
3003
3004 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
3005 ifaceArray = nlohmann::json::array();
3006 if constexpr (bmcwebEnableMultiHost)
3007 {
3008 asyncResp->res.jsonValue["Members@odata.count"] = 0;
3009 // Option currently returns no systems. TBD
3010 return;
3011 }
3012 asyncResp->res.jsonValue["Members@odata.count"] = 1;
3013 nlohmann::json::object_t system;
3014 system["@odata.id"] = "/redfish/v1/Systems/system";
3015 ifaceArray.emplace_back(std::move(system));
3016 sdbusplus::asio::getProperty<std::string>(
3017 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
3018 "/xyz/openbmc_project/network/hypervisor",
3019 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
3020 [asyncResp](const boost::system::error_code& ec2,
3021 const std::string& /*hostName*/) {
3022 if (ec2)
3023 {
3024 return;
3025 }
3026 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
3027 if (val == asyncResp->res.jsonValue.end())
3028 {
Ed Tanous62598e32023-07-17 17:06:25 -07003029 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003030 return;
3031 }
3032 uint64_t* count = val->get_ptr<uint64_t*>();
3033 if (count == nullptr)
3034 {
Ed Tanous62598e32023-07-17 17:06:25 -07003035 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003036 return;
3037 }
3038 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07003039 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003040 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
3041 nlohmann::json::object_t hypervisor;
3042 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
3043 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05003044 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003045}
3046
Yong Lic45f0082019-10-10 14:19:01 +08003047/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003048 * Function transceives data with dbus directly.
3049 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07003050inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003051{
Patrick Williams89492a12023-05-10 07:51:34 -05003052 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
3053 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
3054 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003055 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05003056 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003057
3058 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08003059 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003060 if (ec)
3061 {
Ed Tanous62598e32023-07-17 17:06:25 -07003062 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07003063 messages::internalError(asyncResp->res);
3064 return;
3065 }
3066 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003067 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003068 serviceName, objectPath, interfaceName, method);
3069}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003070
3071/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003072 * Handle error responses from d-bus for system power requests
3073 */
3074inline void handleSystemActionResetError(const boost::system::error_code& ec,
3075 const sdbusplus::message_t& eMsg,
3076 std::string_view resetType,
3077 crow::Response& res)
3078{
3079 if (ec.value() == boost::asio::error::invalid_argument)
3080 {
3081 messages::actionParameterNotSupported(res, resetType, "Reset");
3082 return;
3083 }
3084
3085 if (eMsg.get_error() == nullptr)
3086 {
Ed Tanous62598e32023-07-17 17:06:25 -07003087 BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003088 messages::internalError(res);
3089 return;
3090 }
3091 std::string_view errorMessage = eMsg.get_error()->name;
3092
3093 // If operation failed due to BMC not being in Ready state, tell
3094 // user to retry in a bit
3095 if ((errorMessage ==
3096 std::string_view(
3097 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3098 (errorMessage ==
3099 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3100 {
Ed Tanous62598e32023-07-17 17:06:25 -07003101 BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003102 messages::serviceTemporarilyUnavailable(res, "10");
3103 return;
3104 }
3105
Ed Tanous62598e32023-07-17 17:06:25 -07003106 BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
3107 errorMessage);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003108 messages::internalError(res);
3109}
3110
Ed Tanousc1e219d2023-06-07 10:34:33 -07003111inline void handleComputerSystemResetActionPost(
3112 crow::App& app, const crow::Request& req,
3113 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3114 const std::string& systemName)
3115{
3116 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3117 {
3118 return;
3119 }
3120 if (systemName != "system")
3121 {
3122 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3123 systemName);
3124 return;
3125 }
3126 if constexpr (bmcwebEnableMultiHost)
3127 {
3128 // Option currently returns no systems. TBD
3129 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3130 systemName);
3131 return;
3132 }
3133 std::string resetType;
3134 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3135 {
3136 return;
3137 }
3138
3139 // Get the command and host vs. chassis
3140 std::string command;
3141 bool hostCommand = true;
3142 if ((resetType == "On") || (resetType == "ForceOn"))
3143 {
3144 command = "xyz.openbmc_project.State.Host.Transition.On";
3145 hostCommand = true;
3146 }
3147 else if (resetType == "ForceOff")
3148 {
3149 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3150 hostCommand = false;
3151 }
3152 else if (resetType == "ForceRestart")
3153 {
3154 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3155 hostCommand = true;
3156 }
3157 else if (resetType == "GracefulShutdown")
3158 {
3159 command = "xyz.openbmc_project.State.Host.Transition.Off";
3160 hostCommand = true;
3161 }
3162 else if (resetType == "GracefulRestart")
3163 {
3164 command =
3165 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3166 hostCommand = true;
3167 }
3168 else if (resetType == "PowerCycle")
3169 {
3170 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3171 hostCommand = true;
3172 }
3173 else if (resetType == "Nmi")
3174 {
3175 doNMI(asyncResp);
3176 return;
3177 }
3178 else
3179 {
3180 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3181 return;
3182 }
3183
3184 if (hostCommand)
3185 {
George Liu9ae226f2023-06-21 17:56:46 +08003186 sdbusplus::asio::setProperty(
3187 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3188 "/xyz/openbmc_project/state/host0",
3189 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3190 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003191 [asyncResp, resetType](const boost::system::error_code& ec,
3192 sdbusplus::message_t& sdbusErrMsg) {
3193 if (ec)
3194 {
3195 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3196 asyncResp->res);
3197
3198 return;
3199 }
3200 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003201 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003202 }
3203 else
3204 {
George Liu9ae226f2023-06-21 17:56:46 +08003205 sdbusplus::asio::setProperty(
3206 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3207 "/xyz/openbmc_project/state/chassis0",
3208 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3209 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003210 [asyncResp, resetType](const boost::system::error_code& ec,
3211 sdbusplus::message_t& sdbusErrMsg) {
3212 if (ec)
3213 {
3214 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3215 asyncResp->res);
3216 return;
3217 }
3218 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003219 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003220 }
3221}
3222
Ed Tanousc1e219d2023-06-07 10:34:33 -07003223inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003224 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003225 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3226 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003227{
3228 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3229 {
3230 return;
3231 }
3232
3233 asyncResp->res.addHeader(
3234 boost::beast::http::field::link,
3235 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3236}
3237
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003238inline void afterPortRequest(
3239 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3240 const boost::system::error_code& ec,
3241 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3242{
3243 if (ec)
3244 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003245 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003246 messages::internalError(asyncResp->res);
3247 return;
3248 }
3249 for (const auto& data : socketData)
3250 {
3251 const std::string& socketPath = get<0>(data);
3252 const std::string& protocolName = get<1>(data);
3253 bool isProtocolEnabled = get<2>(data);
3254 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3255 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3256 // need to retrieve port number for
3257 // obmc-console-ssh service
3258 if (protocolName == "SSH")
3259 {
3260 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003261 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003262 int portNumber) {
3263 if (ec1)
3264 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003265 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003266 messages::internalError(asyncResp->res);
3267 return;
3268 }
3269 nlohmann::json& dataJson1 =
3270 asyncResp->res.jsonValue["SerialConsole"];
3271 dataJson1[protocolName]["Port"] = portNumber;
3272 });
3273 }
3274 }
3275}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003276
3277inline void
3278 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3279 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3280 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003281{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003282 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3283 {
3284 return;
3285 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003286
Ed Tanousc1e219d2023-06-07 10:34:33 -07003287 if constexpr (bmcwebEnableMultiHost)
3288 {
3289 // Option currently returns no systems. TBD
3290 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3291 systemName);
3292 return;
3293 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003294
Ed Tanousc1e219d2023-06-07 10:34:33 -07003295 if (systemName == "hypervisor")
3296 {
3297 handleHypervisorSystemGet(asyncResp);
3298 return;
3299 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003300
Ed Tanousc1e219d2023-06-07 10:34:33 -07003301 if (systemName != "system")
3302 {
3303 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3304 systemName);
3305 return;
3306 }
3307 asyncResp->res.addHeader(
3308 boost::beast::http::field::link,
3309 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3310 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003311 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanousc1e219d2023-06-07 10:34:33 -07003312 asyncResp->res.jsonValue["Name"] = "system";
3313 asyncResp->res.jsonValue["Id"] = "system";
3314 asyncResp->res.jsonValue["SystemType"] = "Physical";
3315 asyncResp->res.jsonValue["Description"] = "Computer System";
3316 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3317 if constexpr (bmcwebEnableProcMemStatus)
3318 {
3319 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3320 "Disabled";
3321 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3322 "Disabled";
3323 }
3324 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003325 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003326 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003327
Ed Tanousc1e219d2023-06-07 10:34:33 -07003328 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3329 "/redfish/v1/Systems/system/Processors";
3330 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3331 "/redfish/v1/Systems/system/Memory";
3332 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3333 "/redfish/v1/Systems/system/Storage";
3334 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3335 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003336
Ed Tanousc1e219d2023-06-07 10:34:33 -07003337 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3338 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3339 asyncResp->res
3340 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3341 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003342
Ed Tanousc1e219d2023-06-07 10:34:33 -07003343 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3344 "/redfish/v1/Systems/system/LogServices";
3345 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3346 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003347
Ed Tanousc1e219d2023-06-07 10:34:33 -07003348 nlohmann::json::array_t managedBy;
3349 nlohmann::json& manager = managedBy.emplace_back();
3350 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3351 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3352 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3353 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003354
Ed Tanousc1e219d2023-06-07 10:34:33 -07003355 // Fill in SerialConsole info
3356 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3357 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003358
Ed Tanousc1e219d2023-06-07 10:34:33 -07003359 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3360 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3361 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3362 "Press ~. to exit console";
3363 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3364 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003365
3366#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003367 // Fill in GraphicalConsole info
3368 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3369 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3370 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3371 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003372
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003373#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003374
Ed Tanousc1e219d2023-06-07 10:34:33 -07003375 auto health = std::make_shared<HealthPopulate>(asyncResp);
3376 if constexpr (bmcwebEnableHealthPopulate)
3377 {
3378 constexpr std::array<std::string_view, 4> inventoryForSystems{
3379 "xyz.openbmc_project.Inventory.Item.Dimm",
3380 "xyz.openbmc_project.Inventory.Item.Cpu",
3381 "xyz.openbmc_project.Inventory.Item.Drive",
3382 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003383
Ed Tanousc1e219d2023-06-07 10:34:33 -07003384 dbus::utility::getSubTreePaths(
3385 "/", 0, inventoryForSystems,
3386 [health](const boost::system::error_code& ec,
3387 const std::vector<std::string>& resp) {
3388 if (ec)
3389 {
3390 // no inventory
3391 return;
3392 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003393
Ed Tanousc1e219d2023-06-07 10:34:33 -07003394 health->inventory = resp;
Patrick Williams5a39f772023-10-20 11:20:21 -05003395 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003396 health->populate();
3397 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003398
Ed Tanousc1e219d2023-06-07 10:34:33 -07003399 getMainChassisId(asyncResp,
3400 [](const std::string& chassisId,
3401 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3402 nlohmann::json::array_t chassisArray;
3403 nlohmann::json& chassis = chassisArray.emplace_back();
3404 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3405 chassisId);
3406 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3407 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003408
George Liu59a17e42022-10-08 09:27:47 +08003409 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003410 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3411 getIndicatorLedState(asyncResp);
3412 getComputerSystem(asyncResp, health);
3413 getHostState(asyncResp);
3414 getBootProperties(asyncResp);
3415 getBootProgress(asyncResp);
3416 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003417 pcie_util::getPCIeDeviceList(asyncResp,
3418 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003419 getHostWatchdogTimer(asyncResp);
3420 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003421 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003422 getAutomaticRetryPolicy(asyncResp);
3423 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003424#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003425 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003426#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003427 getTrustedModuleRequiredToBoot(asyncResp);
3428 getPowerMode(asyncResp);
3429 getIdlePowerSaver(asyncResp);
3430}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003431
Ed Tanousc1e219d2023-06-07 10:34:33 -07003432inline void handleComputerSystemPatch(
3433 crow::App& app, const crow::Request& req,
3434 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3435 const std::string& systemName)
3436{
3437 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3438 {
3439 return;
3440 }
3441 if constexpr (bmcwebEnableMultiHost)
3442 {
3443 // Option currently returns no systems. TBD
3444 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3445 systemName);
3446 return;
3447 }
3448 if (systemName != "system")
3449 {
3450 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3451 systemName);
3452 return;
3453 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003454
Ed Tanousc1e219d2023-06-07 10:34:33 -07003455 asyncResp->res.addHeader(
3456 boost::beast::http::field::link,
3457 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003458
Ed Tanousc1e219d2023-06-07 10:34:33 -07003459 std::optional<bool> locationIndicatorActive;
3460 std::optional<std::string> indicatorLed;
3461 std::optional<std::string> assetTag;
3462 std::optional<std::string> powerRestorePolicy;
3463 std::optional<std::string> powerMode;
3464 std::optional<bool> wdtEnable;
3465 std::optional<std::string> wdtTimeOutAction;
3466 std::optional<std::string> bootSource;
3467 std::optional<std::string> bootType;
3468 std::optional<std::string> bootEnable;
3469 std::optional<std::string> bootAutomaticRetry;
3470 std::optional<uint32_t> bootAutomaticRetryAttempts;
3471 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003472 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003473 std::optional<bool> ipsEnable;
3474 std::optional<uint8_t> ipsEnterUtil;
3475 std::optional<uint64_t> ipsEnterTime;
3476 std::optional<uint8_t> ipsExitUtil;
3477 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003478
Ed Tanousc1e219d2023-06-07 10:34:33 -07003479 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003480 if (!json_util::readJsonPatch(
3481 req, asyncResp->res,
3482 "IndicatorLED", indicatorLed,
3483 "LocationIndicatorActive", locationIndicatorActive,
3484 "AssetTag", assetTag,
3485 "PowerRestorePolicy", powerRestorePolicy,
3486 "PowerMode", powerMode,
3487 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3488 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3489 "Boot/BootSourceOverrideTarget", bootSource,
3490 "Boot/BootSourceOverrideMode", bootType,
3491 "Boot/BootSourceOverrideEnabled", bootEnable,
3492 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003493 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003494 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003495 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003496 "IdlePowerSaver/Enabled", ipsEnable,
3497 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3498 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3499 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3500 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3501 {
3502 return;
3503 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003504 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003505
Ed Tanousc1e219d2023-06-07 10:34:33 -07003506 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003507
Ed Tanousc1e219d2023-06-07 10:34:33 -07003508 if (assetTag)
3509 {
3510 setAssetTag(asyncResp, *assetTag);
3511 }
James Feistb49ac872019-05-21 15:12:01 -07003512
Ed Tanousc1e219d2023-06-07 10:34:33 -07003513 if (wdtEnable || wdtTimeOutAction)
3514 {
3515 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3516 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003517
Ed Tanousc1e219d2023-06-07 10:34:33 -07003518 if (bootSource || bootType || bootEnable)
3519 {
3520 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3521 }
3522 if (bootAutomaticRetry)
3523 {
3524 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3525 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003526
Ed Tanousc1e219d2023-06-07 10:34:33 -07003527 if (bootAutomaticRetryAttempts)
3528 {
3529 setAutomaticRetryAttempts(asyncResp,
3530 bootAutomaticRetryAttempts.value());
3531 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003532
Ed Tanousc1e219d2023-06-07 10:34:33 -07003533 if (bootTrustedModuleRequired)
3534 {
3535 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3536 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003537
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003538 if (stopBootOnFault)
3539 {
3540 setStopBootOnFault(asyncResp, *stopBootOnFault);
3541 }
3542
Ed Tanousc1e219d2023-06-07 10:34:33 -07003543 if (locationIndicatorActive)
3544 {
George Liu59a17e42022-10-08 09:27:47 +08003545 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003546 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003547
Ed Tanousc1e219d2023-06-07 10:34:33 -07003548 // TODO (Gunnar): Remove IndicatorLED after enough time has
3549 // passed
3550 if (indicatorLed)
3551 {
3552 setIndicatorLedState(asyncResp, *indicatorLed);
3553 asyncResp->res.addHeader(boost::beast::http::field::warning,
3554 "299 - \"IndicatorLED is deprecated. Use "
3555 "LocationIndicatorActive instead.\"");
3556 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003557
Ed Tanousc1e219d2023-06-07 10:34:33 -07003558 if (powerRestorePolicy)
3559 {
3560 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3561 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003562
Ed Tanousc1e219d2023-06-07 10:34:33 -07003563 if (powerMode)
3564 {
3565 setPowerMode(asyncResp, *powerMode);
3566 }
Chris Cain37bbf982021-09-20 10:53:09 -05003567
Ed Tanousc1e219d2023-06-07 10:34:33 -07003568 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3569 {
3570 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3571 ipsExitUtil, ipsExitTime);
3572 }
3573}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303574
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003575inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003576 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003577 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003578 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003579{
3580 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3581 {
3582 return;
3583 }
3584 asyncResp->res.addHeader(
3585 boost::beast::http::field::link,
3586 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3587}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003588inline void handleSystemCollectionResetActionGet(
3589 crow::App& app, const crow::Request& req,
3590 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3591 const std::string& systemName)
3592{
3593 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3594 {
3595 return;
3596 }
3597 if constexpr (bmcwebEnableMultiHost)
3598 {
3599 // Option currently returns no systems. TBD
3600 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3601 systemName);
3602 return;
3603 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003604
Ed Tanousc1e219d2023-06-07 10:34:33 -07003605 if (systemName == "hypervisor")
3606 {
3607 handleHypervisorResetActionGet(asyncResp);
3608 return;
3609 }
3610
3611 if (systemName != "system")
3612 {
3613 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3614 systemName);
3615 return;
3616 }
3617
3618 asyncResp->res.addHeader(
3619 boost::beast::http::field::link,
3620 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3621
3622 asyncResp->res.jsonValue["@odata.id"] =
3623 "/redfish/v1/Systems/system/ResetActionInfo";
3624 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3625 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3626 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3627
3628 nlohmann::json::array_t parameters;
3629 nlohmann::json::object_t parameter;
3630
3631 parameter["Name"] = "ResetType";
3632 parameter["Required"] = true;
3633 parameter["DataType"] = "String";
3634 nlohmann::json::array_t allowableValues;
3635 allowableValues.emplace_back("On");
3636 allowableValues.emplace_back("ForceOff");
3637 allowableValues.emplace_back("ForceOn");
3638 allowableValues.emplace_back("ForceRestart");
3639 allowableValues.emplace_back("GracefulRestart");
3640 allowableValues.emplace_back("GracefulShutdown");
3641 allowableValues.emplace_back("PowerCycle");
3642 allowableValues.emplace_back("Nmi");
3643 parameter["AllowableValues"] = std::move(allowableValues);
3644 parameters.emplace_back(std::move(parameter));
3645
3646 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3647}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303648/**
3649 * SystemResetActionInfo derived class for delivering Computer Systems
3650 * ResetType AllowableValues using ResetInfo schema.
3651 */
Ed Tanous100afe52023-06-07 13:30:46 -07003652inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303653{
Ed Tanous100afe52023-06-07 13:30:46 -07003654 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3655 .privileges(redfish::privileges::headComputerSystemCollection)
3656 .methods(boost::beast::http::verb::head)(
3657 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3658
3659 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3660 .privileges(redfish::privileges::getComputerSystemCollection)
3661 .methods(boost::beast::http::verb::get)(
3662 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3663
3664 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3665 .privileges(redfish::privileges::headComputerSystem)
3666 .methods(boost::beast::http::verb::head)(
3667 std::bind_front(handleComputerSystemHead, std::ref(app)));
3668
3669 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3670 .privileges(redfish::privileges::getComputerSystem)
3671 .methods(boost::beast::http::verb::get)(
3672 std::bind_front(handleComputerSystemGet, std::ref(app)));
3673
3674 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3675 .privileges(redfish::privileges::patchComputerSystem)
3676 .methods(boost::beast::http::verb::patch)(
3677 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3678
3679 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3680 .privileges(redfish::privileges::postComputerSystem)
3681 .methods(boost::beast::http::verb::post)(std::bind_front(
3682 handleComputerSystemResetActionPost, std::ref(app)));
3683
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003684 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003685 .privileges(redfish::privileges::headActionInfo)
3686 .methods(boost::beast::http::verb::head)(std::bind_front(
3687 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003688 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003689 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003690 .methods(boost::beast::http::verb::get)(std::bind_front(
3691 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003692}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003693} // namespace redfish