blob: 87b413b96b9408ca8d48bf9884caa594fe6a2740 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070023#include "generated/enums/computer_system.hpp"
Andrew Geissler33e1f122024-02-26 21:10:16 -060024#include "generated/enums/resource.hpp"
James Feistb49ac872019-05-21 15:12:01 -070025#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060026#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080027#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070028#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080029#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080030#include "registries/privilege_registry.hpp"
31#include "utils/dbus_utils.hpp"
32#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050033#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080034#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070035#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080036
Andrew Geisslerfc903b32023-05-31 14:15:42 -040037#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070038#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080039#include <boost/system/error_code.hpp>
Andrew Geissler33e1f122024-02-26 21:10:16 -060040#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070041#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070042#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040043#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020044#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050045
George Liu7a1dbc42022-12-07 16:03:22 +080046#include <array>
Andrew Geissler33e1f122024-02-26 21:10:16 -060047#include <memory>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060048#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080049#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080050#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060051#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020052
Ed Tanous1abe55e2018-09-05 08:30:59 -070053namespace redfish
54{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020055
Abhishek Patel5c3e9272021-06-24 10:11:33 -050056const static std::array<std::pair<std::string_view, std::string_view>, 2>
57 protocolToDBusForSystems{
58 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
59
Alpana Kumari9d3ae102019-04-12 06:49:32 -050060/**
61 * @brief Updates the Functional State of DIMMs
62 *
Ed Tanousac106bf2023-06-07 09:24:59 -070063 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050064 * @param[in] dimmState Dimm's Functional state, true/false
65 *
66 * @return None.
67 */
zhanghch058d1b46d2021-04-01 11:18:24 +080068inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070069 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070070 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050071{
Ed Tanous62598e32023-07-17 17:06:25 -070072 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050073
Gunnar Mills4e0453b2020-07-08 14:00:30 -050074 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050075 // Update STATE only if previous State was DISABLED and current Dimm is
76 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070077 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070078 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050079 if (prevMemSummary == "Disabled")
80 {
Ed Tanouse05aec52022-01-25 10:28:56 -080081 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050082 {
Ed Tanousac106bf2023-06-07 09:24:59 -070083 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050084 "Enabled";
85 }
86 }
87}
88
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050090 * @brief Update "ProcessorSummary" "Status" "State" based on
91 * CPU Functional State
92 *
Ed Tanousac106bf2023-06-07 09:24:59 -070093 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050094 * @param[in] cpuFunctionalState is CPU functional true/false
95 *
96 * @return None.
97 */
Ed Tanousac106bf2023-06-07 09:24:59 -070098inline void modifyCpuFunctionalState(
99 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500100{
Ed Tanous62598e32023-07-17 17:06:25 -0700101 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500102
Ed Tanous02cad962022-06-30 16:50:15 -0700103 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700104 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500105
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500106 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500107 // Update STATE only if previous State was Non_Functional and current CPU is
108 // Functional.
109 if (prevProcState == "Disabled")
110 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800111 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500112 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700113 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114 "Enabled";
115 }
116 }
117}
118
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500119/*
120 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
121 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700122 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500123 * @param[in] cpuPresenceState CPU present or not
124 *
125 * @return None.
126 */
127inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700128 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500129 bool isCpuPresent)
130{
Ed Tanous62598e32023-07-17 17:06:25 -0700131 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500132
133 if (isCpuPresent)
134 {
135 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700136 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500137 auto* procCountPtr =
138 procCount.get_ptr<nlohmann::json::number_integer_t*>();
139 if (procCountPtr != nullptr)
140 {
141 // shouldn't be possible to be nullptr
142 *procCountPtr += 1;
143 }
144 }
145}
146
Ali Ahmed382d6472021-09-03 16:53:53 -0500147inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500149 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500151{
Ed Tanous62598e32023-07-17 17:06:25 -0700152 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500153
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200154 // TODO: Get Model
155
156 const uint16_t* coreCount = nullptr;
157
158 const bool success = sdbusplus::unpackPropertiesNoThrow(
159 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
160
161 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500162 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700163 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200164 return;
165 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500166
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200167 if (coreCount != nullptr)
168 {
169 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700170 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200171 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500172
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200173 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500174 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200175 coreCountJson = *coreCount;
176 }
177 else
178 {
179 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500180 }
181 }
182}
183
184/*
185 * @brief Get ProcessorSummary fields
186 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500188 * @param[in] service dbus service for Cpu Information
189 * @param[in] path dbus path for Cpu
190 *
191 * @return None.
192 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700193inline void
194 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500196{
Ed Tanousac106bf2023-06-07 09:24:59 -0700197 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500199 if (ec3)
200 {
Ed Tanous62598e32023-07-17 17:06:25 -0700201 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500202 return;
203 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700204 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500205 };
206
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500207 // Get the Presence of CPU
208 sdbusplus::asio::getProperty<bool>(
209 *crow::connections::systemBus, service, path,
210 "xyz.openbmc_project.Inventory.Item", "Present",
211 std::move(getCpuPresenceState));
212
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500213 if constexpr (bmcwebEnableProcMemStatus)
214 {
215 auto getCpuFunctionalState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700216 [asyncResp](const boost::system::error_code& ec3,
217 const bool cpuFunctionalCheck) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500218 if (ec3)
219 {
Ed Tanous62598e32023-07-17 17:06:25 -0700220 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500221 return;
222 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700223 modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500224 };
Ali Ahmed382d6472021-09-03 16:53:53 -0500225
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500226 // Get the Functional State
227 sdbusplus::asio::getProperty<bool>(
228 *crow::connections::systemBus, service, path,
229 "xyz.openbmc_project.State.Decorator.OperationalStatus",
230 "Functional", std::move(getCpuFunctionalState));
231 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500232
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200233 sdbusplus::asio::getAllProperties(
234 *crow::connections::systemBus, service, path,
235 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700236 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800237 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800238 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700239 if (ec2)
240 {
Ed Tanous62598e32023-07-17 17:06:25 -0700241 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700242 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700243 return;
244 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700245 getProcessorProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500246 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500247}
248
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500249/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500250 * @brief processMemoryProperties fields
251 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700252 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500253 * @param[in] service dbus service for memory Information
254 * @param[in] path dbus path for Memory
255 * @param[in] DBUS properties for memory
256 *
257 * @return None.
258 */
259inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700260 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500261 [[maybe_unused]] const std::string& service,
262 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500263 const dbus::utility::DBusPropertiesMap& properties)
264{
Ed Tanous62598e32023-07-17 17:06:25 -0700265 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500266
267 if (properties.empty())
268 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500269 if constexpr (bmcwebEnableProcMemStatus)
270 {
271 sdbusplus::asio::getProperty<bool>(
272 *crow::connections::systemBus, service, path,
273 "xyz.openbmc_project.State."
274 "Decorator.OperationalStatus",
275 "Functional",
Ed Tanousac106bf2023-06-07 09:24:59 -0700276 [asyncResp](const boost::system::error_code& ec3,
277 bool dimmState) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500278 if (ec3)
279 {
Ed Tanous62598e32023-07-17 17:06:25 -0700280 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500281 return;
282 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700283 updateDimmProperties(asyncResp, dimmState);
Patrick Williams5a39f772023-10-20 11:20:21 -0500284 });
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500285 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500286 return;
287 }
288
289 const size_t* memorySizeInKB = nullptr;
290
291 const bool success = sdbusplus::unpackPropertiesNoThrow(
292 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
293 memorySizeInKB);
294
295 if (!success)
296 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700297 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500298 return;
299 }
300
301 if (memorySizeInKB != nullptr)
302 {
303 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700304 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500305 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500306 if (preValue == nullptr)
307 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700308 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500309 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500310 }
311 else
312 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700313 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500314 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
315 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500316 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500317 if constexpr (bmcwebEnableProcMemStatus)
318 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700319 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500320 "Enabled";
321 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500322 }
323}
324
325/*
326 * @brief Get getMemorySummary fields
327 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700328 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500329 * @param[in] service dbus service for memory Information
330 * @param[in] path dbus path for memory
331 *
332 * @return None.
333 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700334inline void
335 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
336 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500337{
338 sdbusplus::asio::getAllProperties(
339 *crow::connections::systemBus, service, path,
340 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700341 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500342 path](const boost::system::error_code& ec2,
343 const dbus::utility::DBusPropertiesMap& properties) {
344 if (ec2)
345 {
Ed Tanous62598e32023-07-17 17:06:25 -0700346 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700347 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500348 return;
349 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700350 processMemoryProperties(asyncResp, service, path, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500351 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500352}
353
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500354inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
355 const boost::system::error_code& ec,
356 const dbus::utility::DBusPropertiesMap& properties)
357{
358 if (ec)
359 {
360 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
361 messages::internalError(asyncResp->res);
362 return;
363 }
364 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
365
366 const std::string* uUID = nullptr;
367
368 const bool success = sdbusplus::unpackPropertiesNoThrow(
369 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
370
371 if (!success)
372 {
373 messages::internalError(asyncResp->res);
374 return;
375 }
376
377 if (uUID != nullptr)
378 {
379 std::string valueStr = *uUID;
380 if (valueStr.size() == 32)
381 {
382 valueStr.insert(8, 1, '-');
383 valueStr.insert(13, 1, '-');
384 valueStr.insert(18, 1, '-');
385 valueStr.insert(23, 1, '-');
386 }
387 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
388 asyncResp->res.jsonValue["UUID"] = valueStr;
389 }
390}
391
392inline void
393 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
394 const boost::system::error_code& ec,
395 const dbus::utility::DBusPropertiesMap& propertiesList)
396{
397 if (ec)
398 {
399 // doesn't have to include this
400 // interface
401 return;
402 }
403 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
404
405 const std::string* partNumber = nullptr;
406 const std::string* serialNumber = nullptr;
407 const std::string* manufacturer = nullptr;
408 const std::string* model = nullptr;
409 const std::string* subModel = nullptr;
410
411 const bool success = sdbusplus::unpackPropertiesNoThrow(
412 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
413 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
414 "Model", model, "SubModel", subModel);
415
416 if (!success)
417 {
418 messages::internalError(asyncResp->res);
419 return;
420 }
421
422 if (partNumber != nullptr)
423 {
424 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
425 }
426
427 if (serialNumber != nullptr)
428 {
429 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
430 }
431
432 if (manufacturer != nullptr)
433 {
434 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
435 }
436
437 if (model != nullptr)
438 {
439 asyncResp->res.jsonValue["Model"] = *model;
440 }
441
442 if (subModel != nullptr)
443 {
444 asyncResp->res.jsonValue["SubModel"] = *subModel;
445 }
446
447 // Grab the bios version
448 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
449 "BiosVersion", false);
450}
451
452inline void
453 afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
454 const boost::system::error_code& ec,
455 const std::string& value)
456{
457 if (ec)
458 {
459 // doesn't have to include this
460 // interface
461 return;
462 }
463
464 asyncResp->res.jsonValue["AssetTag"] = value;
465}
466
467inline void afterSystemGetSubTree(
468 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
469 const std::shared_ptr<HealthPopulate>& systemHealth,
470 const boost::system::error_code& ec,
471 const dbus::utility::MapperGetSubTreeResponse& subtree)
472{
473 if (ec)
474 {
475 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
476 messages::internalError(asyncResp->res);
477 return;
478 }
479 // Iterate over all retrieved ObjectPaths.
480 for (const std::pair<
481 std::string,
482 std::vector<std::pair<std::string, std::vector<std::string>>>>&
483 object : subtree)
484 {
485 const std::string& path = object.first;
486 BMCWEB_LOG_DEBUG("Got path: {}", path);
487 const std::vector<std::pair<std::string, std::vector<std::string>>>&
488 connectionNames = object.second;
489 if (connectionNames.empty())
490 {
491 continue;
492 }
493
494 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
495 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
496
497 if constexpr (bmcwebEnableProcMemStatus)
498 {
499 memoryHealth = std::make_shared<HealthPopulate>(
500 asyncResp, "/MemorySummary/Status"_json_pointer);
501 systemHealth->children.emplace_back(memoryHealth);
502
503 if constexpr (bmcwebEnableHealthPopulate)
504 {
505 cpuHealth = std::make_shared<HealthPopulate>(
506 asyncResp, "/ProcessorSummary/Status"_json_pointer);
507
508 systemHealth->children.emplace_back(cpuHealth);
509 }
510 }
511
512 // This is not system, so check if it's cpu, dimm, UUID or
513 // BiosVer
514 for (const auto& connection : connectionNames)
515 {
516 for (const auto& interfaceName : connection.second)
517 {
518 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
519 {
520 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
521
522 getMemorySummary(asyncResp, connection.first, path);
523
524 if constexpr (bmcwebEnableProcMemStatus)
525 {
526 memoryHealth->inventory.emplace_back(path);
527 }
528 }
529 else if (interfaceName ==
530 "xyz.openbmc_project.Inventory.Item.Cpu")
531 {
532 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
533
534 getProcessorSummary(asyncResp, connection.first, path);
535
536 if constexpr (bmcwebEnableProcMemStatus)
537 {
538 cpuHealth->inventory.emplace_back(path);
539 }
540 }
541 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
542 {
543 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
544
545 sdbusplus::asio::getAllProperties(
546 *crow::connections::systemBus, connection.first, path,
547 "xyz.openbmc_project.Common.UUID",
548 [asyncResp](const boost::system::error_code& ec3,
549 const dbus::utility::DBusPropertiesMap&
550 properties) {
551 afterGetUUID(asyncResp, ec3, properties);
552 });
553 }
554 else if (interfaceName ==
555 "xyz.openbmc_project.Inventory.Item.System")
556 {
557 sdbusplus::asio::getAllProperties(
558 *crow::connections::systemBus, connection.first, path,
559 "xyz.openbmc_project.Inventory.Decorator.Asset",
560 [asyncResp](const boost::system::error_code& ec3,
561 const dbus::utility::DBusPropertiesMap&
562 properties) {
563 afterGetInventory(asyncResp, ec3, properties);
564 });
565
566 sdbusplus::asio::getProperty<std::string>(
567 *crow::connections::systemBus, connection.first, path,
568 "xyz.openbmc_project.Inventory.Decorator."
569 "AssetTag",
570 "AssetTag",
571 std::bind_front(afterGetAssetTag, asyncResp));
572 }
573 }
574 }
575 }
576}
577
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500578/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700579 * @brief Retrieves computer system properties over dbus
580 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700581 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500582 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700583 *
584 * @return None.
585 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700586inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700587 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700588 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700589{
Ed Tanous62598e32023-07-17 17:06:25 -0700590 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800591 constexpr std::array<std::string_view, 5> interfaces = {
592 "xyz.openbmc_project.Inventory.Decorator.Asset",
593 "xyz.openbmc_project.Inventory.Item.Cpu",
594 "xyz.openbmc_project.Inventory.Item.Dimm",
595 "xyz.openbmc_project.Inventory.Item.System",
596 "xyz.openbmc_project.Common.UUID",
597 };
598 dbus::utility::getSubTree(
599 "/xyz/openbmc_project/inventory", 0, interfaces,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500600 std::bind_front(afterSystemGetSubTree, asyncResp, systemHealth));
Ed Tanous6c34de42018-08-29 13:37:36 -0700601}
602
603/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700604 * @brief Retrieves host state properties over dbus
605 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700606 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700607 *
608 * @return None.
609 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700610inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700611{
Ed Tanous62598e32023-07-17 17:06:25 -0700612 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700613 sdbusplus::asio::getProperty<std::string>(
614 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
615 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
616 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700617 [asyncResp](const boost::system::error_code& ec,
618 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700619 if (ec)
620 {
621 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700622 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700623 // Service not available, no error, just don't return
624 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700625 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700626 return;
627 }
Ed Tanous62598e32023-07-17 17:06:25 -0700628 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700629 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700630 return;
631 }
Ed Tanous66173382018-08-15 18:20:59 -0700632
Ed Tanous62598e32023-07-17 17:06:25 -0700633 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700634 // Verify Host State
635 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
636 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700637 asyncResp->res.jsonValue["PowerState"] = "On";
638 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700639 }
640 else if (hostState ==
641 "xyz.openbmc_project.State.Host.HostState.Quiesced")
642 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700643 asyncResp->res.jsonValue["PowerState"] = "On";
644 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700645 }
646 else if (hostState ==
647 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
648 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700649 asyncResp->res.jsonValue["PowerState"] = "On";
650 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700651 }
652 else if (
653 hostState ==
654 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
655 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700656 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
657 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700658 }
659 else if (hostState ==
660 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
661 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700662 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
663 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700664 }
665 else
666 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700667 asyncResp->res.jsonValue["PowerState"] = "Off";
668 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700669 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500670 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700671}
672
673/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500674 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530675 *
676 * @param[in] dbusSource The boot source in DBUS speak.
677 *
678 * @return Returns as a string, the boot source in Redfish terms. If translation
679 * cannot be done, returns an empty string.
680 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000681inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682{
683 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
684 {
685 return "None";
686 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700687 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530688 {
689 return "Hdd";
690 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700691 if (dbusSource ==
692 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530693 {
694 return "Cd";
695 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700696 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530697 {
698 return "Pxe";
699 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700700 if (dbusSource ==
701 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700702 {
703 return "Usb";
704 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700705 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530706}
707
708/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300709 * @brief Translates boot type DBUS property value to redfish.
710 *
711 * @param[in] dbusType The boot type in DBUS speak.
712 *
713 * @return Returns as a string, the boot type in Redfish terms. If translation
714 * cannot be done, returns an empty string.
715 */
716inline std::string dbusToRfBootType(const std::string& dbusType)
717{
718 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
719 {
720 return "Legacy";
721 }
722 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
723 {
724 return "UEFI";
725 }
726 return "";
727}
728
729/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500730 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530731 *
732 * @param[in] dbusMode The boot mode in DBUS speak.
733 *
734 * @return Returns as a string, the boot mode in Redfish terms. If translation
735 * cannot be done, returns an empty string.
736 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000737inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530738{
739 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
740 {
741 return "None";
742 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700743 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530744 {
745 return "Diags";
746 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700747 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530748 {
749 return "BiosSetup";
750 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700751 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530752}
753
754/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600755 * @brief Translates boot progress DBUS property value to redfish.
756 *
757 * @param[in] dbusBootProgress The boot progress in DBUS speak.
758 *
759 * @return Returns as a string, the boot progress in Redfish terms. If
760 * translation cannot be done, returns "None".
761 */
762inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
763{
764 // Now convert the D-Bus BootProgress to the appropriate Redfish
765 // enum
766 std::string rfBpLastState = "None";
767 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
768 "ProgressStages.Unspecified")
769 {
770 rfBpLastState = "None";
771 }
772 else if (dbusBootProgress ==
773 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
774 "PrimaryProcInit")
775 {
776 rfBpLastState = "PrimaryProcessorInitializationStarted";
777 }
778 else if (dbusBootProgress ==
779 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
780 "BusInit")
781 {
782 rfBpLastState = "BusInitializationStarted";
783 }
784 else if (dbusBootProgress ==
785 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
786 "MemoryInit")
787 {
788 rfBpLastState = "MemoryInitializationStarted";
789 }
790 else if (dbusBootProgress ==
791 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
792 "SecondaryProcInit")
793 {
794 rfBpLastState = "SecondaryProcessorInitializationStarted";
795 }
796 else if (dbusBootProgress ==
797 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
798 "PCIInit")
799 {
800 rfBpLastState = "PCIResourceConfigStarted";
801 }
802 else if (dbusBootProgress ==
803 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
804 "SystemSetup")
805 {
806 rfBpLastState = "SetupEntered";
807 }
808 else if (dbusBootProgress ==
809 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
810 "SystemInitComplete")
811 {
812 rfBpLastState = "SystemHardwareInitializationComplete";
813 }
814 else if (dbusBootProgress ==
815 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
816 "OSStart")
817 {
818 rfBpLastState = "OSBootStarted";
819 }
820 else if (dbusBootProgress ==
821 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
822 "OSRunning")
823 {
824 rfBpLastState = "OSRunning";
825 }
826 else
827 {
Ed Tanous62598e32023-07-17 17:06:25 -0700828 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600829 // Just return the default
830 }
831 return rfBpLastState;
832}
833
834/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500835 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530836 *
837 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700838 * @param[out] bootSource The DBus source
839 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530840 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700841 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530842 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700843inline int
844 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
845 const std::string& rfSource, std::string& bootSource,
846 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530847{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300848 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
849 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700850
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530851 if (rfSource == "None")
852 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700853 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530854 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700855 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530856 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700857 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
858 }
859 else if (rfSource == "Hdd")
860 {
861 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
862 }
863 else if (rfSource == "Diags")
864 {
865 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
866 }
867 else if (rfSource == "Cd")
868 {
869 bootSource =
870 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
871 }
872 else if (rfSource == "BiosSetup")
873 {
874 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530875 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700876 else if (rfSource == "Usb")
877 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700878 bootSource =
879 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700880 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530881 else
882 {
Ed Tanous62598e32023-07-17 17:06:25 -0700883 BMCWEB_LOG_DEBUG(
884 "Invalid property value for BootSourceOverrideTarget: {}",
885 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700886 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700887 "BootSourceTargetOverride");
888 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530889 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700890 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530891}
Ali Ahmed19817712021-06-29 17:01:52 -0500892
Andrew Geissler978b8802020-11-19 13:36:40 -0600893/**
894 * @brief Retrieves boot progress of the system
895 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700896 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600897 *
898 * @return None.
899 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700900inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600901{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700902 sdbusplus::asio::getProperty<std::string>(
903 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
904 "/xyz/openbmc_project/state/host0",
905 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700906 [asyncResp](const boost::system::error_code& ec,
907 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700908 if (ec)
909 {
910 // BootProgress is an optional object so just do nothing if
911 // not found
912 return;
913 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600914
Ed Tanous62598e32023-07-17 17:06:25 -0700915 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600916
Ed Tanousac106bf2023-06-07 09:24:59 -0700917 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700918 dbusToRfBootProgress(bootProgressStr);
Patrick Williams5a39f772023-10-20 11:20:21 -0500919 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600920}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530921
922/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000923 * @brief Retrieves boot progress Last Update of the system
924 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700925 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000926 *
927 * @return None.
928 */
929inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700930 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000931{
932 sdbusplus::asio::getProperty<uint64_t>(
933 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
934 "/xyz/openbmc_project/state/host0",
935 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700936 [asyncResp](const boost::system::error_code& ec,
937 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000938 if (ec)
939 {
Ed Tanous62598e32023-07-17 17:06:25 -0700940 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000941 return;
942 }
943
944 // BootProgressLastUpdate is the last time the BootProgress property
945 // was updated. The time is the Epoch time, number of microseconds
946 // since 1 Jan 1970 00::00::00 UTC."
947 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
948 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
949
950 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700951 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000952 redfish::time_utils::getDateTimeUintUs(lastStateTime);
Patrick Williams5a39f772023-10-20 11:20:21 -0500953 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000954}
955
956/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300957 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300958 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700959 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300960 *
961 * @return None.
962 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300963
Ed Tanousac106bf2023-06-07 09:24:59 -0700964inline void
965 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300966{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700967 sdbusplus::asio::getProperty<std::string>(
968 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
969 "/xyz/openbmc_project/control/host0/boot",
970 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700971 [asyncResp](const boost::system::error_code& ec,
972 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700973 if (ec)
974 {
975 // not an error, don't have to have the interface
976 return;
977 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300978
Ed Tanous62598e32023-07-17 17:06:25 -0700979 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300980
Ed Tanousac106bf2023-06-07 09:24:59 -0700981 asyncResp->res
982 .jsonValue["Boot"]
983 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700984 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300985
Ed Tanous002d39b2022-05-31 08:59:27 -0700986 auto rfType = dbusToRfBootType(bootType);
987 if (rfType.empty())
988 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700989 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700990 return;
991 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300992
Ed Tanousac106bf2023-06-07 09:24:59 -0700993 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Patrick Williams5a39f772023-10-20 11:20:21 -0500994 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300995}
996
997/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300998 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530999 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001000 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301001 *
1002 * @return None.
1003 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001004
Ed Tanousac106bf2023-06-07 09:24:59 -07001005inline void
1006 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301007{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001008 sdbusplus::asio::getProperty<std::string>(
1009 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1010 "/xyz/openbmc_project/control/host0/boot",
1011 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001012 [asyncResp](const boost::system::error_code& ec,
1013 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001014 if (ec)
1015 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001016 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001017 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001018 return;
1019 }
1020
Ed Tanous62598e32023-07-17 17:06:25 -07001021 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -07001022
Ed Tanousac106bf2023-06-07 09:24:59 -07001023 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001024 .jsonValue["Boot"]
1025 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1026 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1027
1028 if (bootModeStr !=
1029 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1030 {
1031 auto rfMode = dbusToRfBootMode(bootModeStr);
1032 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301033 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001034 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001035 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301036 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001037 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001038 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301039}
1040
1041/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001042 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301043 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001044 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301045 *
1046 * @return None.
1047 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001048
1049inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001050 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301051{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001052 sdbusplus::asio::getProperty<std::string>(
1053 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1054 "/xyz/openbmc_project/control/host0/boot",
1055 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001056 [asyncResp](const boost::system::error_code& ec,
1057 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001058 if (ec)
1059 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001060 if (ec.value() == boost::asio::error::host_unreachable)
1061 {
1062 return;
1063 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001064 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001065 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001066 return;
1067 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301068
Ed Tanous62598e32023-07-17 17:06:25 -07001069 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301070
Ed Tanous002d39b2022-05-31 08:59:27 -07001071 auto rfSource = dbusToRfBootSource(bootSourceStr);
1072 if (!rfSource.empty())
1073 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001074 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1075 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001076 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001077
Ed Tanous002d39b2022-05-31 08:59:27 -07001078 // Get BootMode as BootSourceOverrideTarget is constructed
1079 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001080 getBootOverrideMode(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001081 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301082}
1083
1084/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001085 * @brief This functions abstracts all the logic behind getting a
1086 * "BootSourceOverrideEnabled" property from an overall boot override enable
1087 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301088 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001089 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301090 *
1091 * @return None.
1092 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301093
Ed Tanousac106bf2023-06-07 09:24:59 -07001094inline void processBootOverrideEnable(
1095 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1096 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001097{
1098 if (!bootOverrideEnableSetting)
1099 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001100 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1101 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001102 return;
1103 }
1104
1105 // If boot source override is enabled, we need to check 'one_time'
1106 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001107 sdbusplus::asio::getProperty<bool>(
1108 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1109 "/xyz/openbmc_project/control/host0/boot/one_time",
1110 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001111 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001112 if (ec)
1113 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001114 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001115 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001116 return;
1117 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301118
Ed Tanous002d39b2022-05-31 08:59:27 -07001119 if (oneTimeSetting)
1120 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001121 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1122 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001123 }
1124 else
1125 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001126 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001127 "Continuous";
1128 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001129 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301130}
1131
1132/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001133 * @brief Retrieves boot override enable over DBUS
1134 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001135 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001136 *
1137 * @return None.
1138 */
1139
1140inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001141 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001142{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001143 sdbusplus::asio::getProperty<bool>(
1144 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1145 "/xyz/openbmc_project/control/host0/boot",
1146 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001147 [asyncResp](const boost::system::error_code& ec,
1148 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001149 if (ec)
1150 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001151 if (ec.value() == boost::asio::error::host_unreachable)
1152 {
1153 return;
1154 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001155 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001156 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001157 return;
1158 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001159
Ed Tanousac106bf2023-06-07 09:24:59 -07001160 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Patrick Williams5a39f772023-10-20 11:20:21 -05001161 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001162}
1163
1164/**
1165 * @brief Retrieves boot source override properties
1166 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001167 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001168 *
1169 * @return None.
1170 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001171inline void
1172 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001173{
Ed Tanous62598e32023-07-17 17:06:25 -07001174 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001175
Ed Tanousac106bf2023-06-07 09:24:59 -07001176 getBootOverrideSource(asyncResp);
1177 getBootOverrideType(asyncResp);
1178 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001179}
1180
1181/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001182 * @brief Retrieves the Last Reset Time
1183 *
1184 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1185 * and power off. Even though this is the "system" Redfish object look at the
1186 * chassis D-Bus interface for the LastStateChangeTime since this has the
1187 * last power operation time.
1188 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001189 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001190 *
1191 * @return None.
1192 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001193inline void
1194 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001195{
Ed Tanous62598e32023-07-17 17:06:25 -07001196 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001197
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001198 sdbusplus::asio::getProperty<uint64_t>(
1199 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1200 "/xyz/openbmc_project/state/chassis0",
1201 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001202 [asyncResp](const boost::system::error_code& ec,
1203 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001204 if (ec)
1205 {
Ed Tanous62598e32023-07-17 17:06:25 -07001206 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001207 return;
1208 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001209
Ed Tanous002d39b2022-05-31 08:59:27 -07001210 // LastStateChangeTime is epoch time, in milliseconds
1211 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1212 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001213
Ed Tanous002d39b2022-05-31 08:59:27 -07001214 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001215 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001216 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001217 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001218}
1219
1220/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001221 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1222 *
1223 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1224 * corresponding property "AttemptsLeft" that keeps track of the amount of
1225 * automatic retry attempts left are hosted in phosphor-state-manager through
1226 * dbus.
1227 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001228 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001229 *
1230 * @return None.
1231 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001232inline void getAutomaticRebootAttempts(
1233 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001234{
Ed Tanous62598e32023-07-17 17:06:25 -07001235 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001236
1237 sdbusplus::asio::getAllProperties(
1238 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1239 "/xyz/openbmc_project/state/host0",
1240 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001241 [asyncResp{asyncResp}](
1242 const boost::system::error_code& ec,
1243 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001244 if (ec)
1245 {
1246 if (ec.value() != EBADR)
1247 {
Ed Tanous62598e32023-07-17 17:06:25 -07001248 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001249 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001250 }
1251 return;
1252 }
1253
1254 const uint32_t* attemptsLeft = nullptr;
1255 const uint32_t* retryAttempts = nullptr;
1256
1257 const bool success = sdbusplus::unpackPropertiesNoThrow(
1258 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1259 attemptsLeft, "RetryAttempts", retryAttempts);
1260
1261 if (!success)
1262 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001263 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001264 return;
1265 }
1266
1267 if (attemptsLeft != nullptr)
1268 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001269 asyncResp->res
1270 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001271 *attemptsLeft;
1272 }
1273
1274 if (retryAttempts != nullptr)
1275 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001276 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001277 *retryAttempts;
1278 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001279 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001280}
1281
1282/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001283 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1284 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001285 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001286 *
1287 * @return None.
1288 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001289inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001290 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001291{
Ed Tanous62598e32023-07-17 17:06:25 -07001292 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001293
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001294 sdbusplus::asio::getProperty<bool>(
1295 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1296 "/xyz/openbmc_project/control/host0/auto_reboot",
1297 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001298 [asyncResp](const boost::system::error_code& ec,
1299 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001300 if (ec)
1301 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001302 if (ec.value() != EBADR)
1303 {
Ed Tanous62598e32023-07-17 17:06:25 -07001304 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001305 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001306 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001307 return;
1308 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001309
Ed Tanous62598e32023-07-17 17:06:25 -07001310 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001311 if (autoRebootEnabled)
1312 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001313 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001314 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001315 }
1316 else
1317 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001318 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1319 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001320 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001321 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001322
Ed Tanous002d39b2022-05-31 08:59:27 -07001323 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1324 // and RetryAttempts. OpenBMC only supports Disabled and
1325 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001326 asyncResp->res
1327 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1328 {"Disabled", "RetryAttempts"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001329 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001330}
1331
1332/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001333 * @brief Sets RetryAttempts
1334 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001335 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001336 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1337 *
1338 *@return None.
1339 */
1340
Ed Tanousac106bf2023-06-07 09:24:59 -07001341inline void setAutomaticRetryAttempts(
1342 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1343 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001344{
Ed Tanous62598e32023-07-17 17:06:25 -07001345 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001346 sdbusplus::asio::setProperty(
1347 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1348 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001349 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001350 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001351 if (ec)
1352 {
1353 BMCWEB_LOG_ERROR(
1354 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1355 messages::internalError(asyncResp->res);
1356 return;
1357 }
1358 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001359}
1360
Ed Tanous8d69c662023-06-21 10:29:06 -07001361inline computer_system::PowerRestorePolicyTypes
1362 redfishPowerRestorePolicyFromDbus(std::string_view value)
1363{
1364 if (value ==
1365 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1366 {
1367 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1368 }
1369 if (value ==
1370 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1371 {
1372 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1373 }
1374 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001375 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001376 {
1377 return computer_system::PowerRestorePolicyTypes::LastState;
1378 }
1379 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1380 {
1381 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1382 }
1383 return computer_system::PowerRestorePolicyTypes::Invalid;
1384}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001385/**
George Liuc6a620f2020-04-10 17:18:11 +08001386 * @brief Retrieves power restore policy over DBUS.
1387 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001388 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001389 *
1390 * @return None.
1391 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001392inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001393 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001394{
Ed Tanous62598e32023-07-17 17:06:25 -07001395 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001396
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001397 sdbusplus::asio::getProperty<std::string>(
1398 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1399 "/xyz/openbmc_project/control/host0/power_restore_policy",
1400 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001401 [asyncResp](const boost::system::error_code& ec,
1402 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001403 if (ec)
1404 {
Ed Tanous62598e32023-07-17 17:06:25 -07001405 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001406 return;
1407 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001408 computer_system::PowerRestorePolicyTypes restore =
1409 redfishPowerRestorePolicyFromDbus(policy);
1410 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001411 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001412 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001413 return;
1414 }
George Liuc6a620f2020-04-10 17:18:11 +08001415
Ed Tanous8d69c662023-06-21 10:29:06 -07001416 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Patrick Williams5a39f772023-10-20 11:20:21 -05001417 });
George Liuc6a620f2020-04-10 17:18:11 +08001418}
1419
1420/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001421 * @brief Stop Boot On Fault over DBUS.
1422 *
1423 * @param[in] asyncResp Shared pointer for generating response message.
1424 *
1425 * @return None.
1426 */
1427inline void
1428 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1429{
Ed Tanous62598e32023-07-17 17:06:25 -07001430 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001431
1432 sdbusplus::asio::getProperty<bool>(
1433 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1434 "/xyz/openbmc_project/logging/settings",
1435 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1436 [asyncResp](const boost::system::error_code& ec, bool value) {
1437 if (ec)
1438 {
1439 if (ec.value() != EBADR)
1440 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001441 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001442 messages::internalError(asyncResp->res);
1443 }
1444 return;
1445 }
1446
1447 if (value)
1448 {
1449 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1450 }
1451 else
1452 {
1453 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1454 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001455 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001456}
1457
1458/**
Ali Ahmed19817712021-06-29 17:01:52 -05001459 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1460 * TPM is required for booting the host.
1461 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001462 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001463 *
1464 * @return None.
1465 */
1466inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001467 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001468{
Ed Tanous62598e32023-07-17 17:06:25 -07001469 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001470 constexpr std::array<std::string_view, 1> interfaces = {
1471 "xyz.openbmc_project.Control.TPM.Policy"};
1472 dbus::utility::getSubTree(
1473 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001474 [asyncResp](const boost::system::error_code& ec,
1475 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001476 if (ec)
1477 {
Ed Tanous62598e32023-07-17 17:06:25 -07001478 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1479 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001480 // This is an optional D-Bus object so just return if
1481 // error occurs
1482 return;
1483 }
1484 if (subtree.empty())
1485 {
1486 // As noted above, this is an optional interface so just return
1487 // if there is no instance found
1488 return;
1489 }
1490
1491 /* When there is more than one TPMEnable object... */
1492 if (subtree.size() > 1)
1493 {
Ed Tanous62598e32023-07-17 17:06:25 -07001494 BMCWEB_LOG_DEBUG(
1495 "DBUS response has more than 1 TPM Enable object:{}",
1496 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001497 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001498 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001499 return;
1500 }
1501
1502 // Make sure the Dbus response map has a service and objectPath
1503 // field
1504 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1505 {
Ed Tanous62598e32023-07-17 17:06:25 -07001506 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001507 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001508 return;
1509 }
1510
1511 const std::string& path = subtree[0].first;
1512 const std::string& serv = subtree[0].second.begin()->first;
1513
1514 // Valid TPM Enable object found, now reading the current value
1515 sdbusplus::asio::getProperty<bool>(
1516 *crow::connections::systemBus, serv, path,
1517 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001518 [asyncResp](const boost::system::error_code& ec2,
1519 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001520 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001521 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001522 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001523 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001524 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001525 return;
1526 }
1527
Ed Tanous002d39b2022-05-31 08:59:27 -07001528 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001529 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001530 asyncResp->res
1531 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001532 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001533 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001534 else
1535 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001536 asyncResp->res
1537 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001538 "Disabled";
1539 }
George Liue99073f2022-12-09 11:06:16 +08001540 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001541 });
Ali Ahmed19817712021-06-29 17:01:52 -05001542}
1543
1544/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001545 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1546 * TPM is required for booting the host.
1547 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001548 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001549 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1550 *
1551 * @return None.
1552 */
1553inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001554 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001555{
Ed Tanous62598e32023-07-17 17:06:25 -07001556 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001557 constexpr std::array<std::string_view, 1> interfaces = {
1558 "xyz.openbmc_project.Control.TPM.Policy"};
1559 dbus::utility::getSubTree(
1560 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001561 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001562 tpmRequired](const boost::system::error_code& ec,
1563 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001564 if (ec)
1565 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001566 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001567 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001568 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001569 return;
1570 }
1571 if (subtree.empty())
1572 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001573 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001574 "TrustedModuleRequiredToBoot");
1575 return;
1576 }
1577
1578 /* When there is more than one TPMEnable object... */
1579 if (subtree.size() > 1)
1580 {
Ed Tanous62598e32023-07-17 17:06:25 -07001581 BMCWEB_LOG_DEBUG(
1582 "DBUS response has more than 1 TPM Enable object:{}",
1583 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001584 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001585 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001586 return;
1587 }
1588
1589 // Make sure the Dbus response map has a service and objectPath
1590 // field
1591 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1592 {
Ed Tanous62598e32023-07-17 17:06:25 -07001593 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001594 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001595 return;
1596 }
1597
1598 const std::string& path = subtree[0].first;
1599 const std::string& serv = subtree[0].second.begin()->first;
1600
1601 if (serv.empty())
1602 {
Ed Tanous62598e32023-07-17 17:06:25 -07001603 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001604 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001605 return;
1606 }
1607
1608 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001609 sdbusplus::asio::setProperty(
1610 *crow::connections::systemBus, serv, path,
1611 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001612 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001613 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001614 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001615 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001616 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1617 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001618 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001619 return;
1620 }
Ed Tanous62598e32023-07-17 17:06:25 -07001621 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001622 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001623 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001624}
1625
1626/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301627 * @brief Sets boot properties into DBUS object(s).
1628 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001629 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001630 * @param[in] bootType The boot type to set.
1631 * @return Integer error code.
1632 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001633inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001634 const std::optional<std::string>& bootType)
1635{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001636 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001637
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001638 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001639 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001640 return;
1641 }
1642
1643 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001644 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001645 // Figure out which DBUS interface and property to use
1646 if (*bootType == "Legacy")
1647 {
1648 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1649 }
1650 else if (*bootType == "UEFI")
1651 {
1652 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1653 }
1654 else
1655 {
Ed Tanous62598e32023-07-17 17:06:25 -07001656 BMCWEB_LOG_DEBUG("Invalid property value for "
1657 "BootSourceOverrideMode: {}",
1658 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001659 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001660 "BootSourceOverrideMode");
1661 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001662 }
1663
1664 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001665 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001666
George Liu9ae226f2023-06-21 17:56:46 +08001667 sdbusplus::asio::setProperty(
1668 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1669 "/xyz/openbmc_project/control/host0/boot",
1670 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001671 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001672 if (ec)
1673 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001674 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001675 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001676 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001677 return;
1678 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001679 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001680 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001681 return;
1682 }
Ed Tanous62598e32023-07-17 17:06:25 -07001683 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001684 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001685}
1686
1687/**
1688 * @brief Sets boot properties into DBUS object(s).
1689 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001690 * @param[in] asyncResp Shared pointer for generating response
1691 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001692 * @param[in] bootType The boot type to set.
1693 * @return Integer error code.
1694 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001695inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001696 const std::optional<std::string>& bootEnable)
1697{
1698 if (!bootEnable)
1699 {
1700 return;
1701 }
1702 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001703 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001704
1705 bool bootOverrideEnable = false;
1706 bool bootOverridePersistent = false;
1707 // Figure out which DBUS interface and property to use
1708 if (*bootEnable == "Disabled")
1709 {
1710 bootOverrideEnable = false;
1711 }
1712 else if (*bootEnable == "Once")
1713 {
1714 bootOverrideEnable = true;
1715 bootOverridePersistent = false;
1716 }
1717 else if (*bootEnable == "Continuous")
1718 {
1719 bootOverrideEnable = true;
1720 bootOverridePersistent = true;
1721 }
1722 else
1723 {
Ed Tanous62598e32023-07-17 17:06:25 -07001724 BMCWEB_LOG_DEBUG(
1725 "Invalid property value for BootSourceOverrideEnabled: {}",
1726 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001727 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001728 "BootSourceOverrideEnabled");
1729 return;
1730 }
1731
1732 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001733 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001734
George Liu9ae226f2023-06-21 17:56:46 +08001735 sdbusplus::asio::setProperty(
1736 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1737 "/xyz/openbmc_project/control/host0/boot",
1738 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001739 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001740 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001741 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001742 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001743 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001744 return;
1745 }
Ed Tanous62598e32023-07-17 17:06:25 -07001746 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001747 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001748
1749 if (!bootOverrideEnable)
1750 {
1751 return;
1752 }
1753
1754 // In case boot override is enabled we need to set correct value for the
1755 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001756 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1757 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001758
George Liu9ae226f2023-06-21 17:56:46 +08001759 sdbusplus::asio::setProperty(
1760 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1761 "/xyz/openbmc_project/control/host0/boot/one_time",
1762 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001763 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001764 if (ec)
1765 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001766 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001767 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001768 return;
1769 }
Ed Tanous62598e32023-07-17 17:06:25 -07001770 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001771 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001772}
1773
1774/**
1775 * @brief Sets boot properties into DBUS object(s).
1776 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001777 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301778 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301779 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001780 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301781 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001782inline void
1783 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1784 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301785{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001786 std::string bootSourceStr;
1787 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001788
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001789 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301790 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001791 return;
1792 }
1793
1794 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001795 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001796 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001797 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1798 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001799 {
Ed Tanous62598e32023-07-17 17:06:25 -07001800 BMCWEB_LOG_DEBUG(
1801 "Invalid property value for BootSourceOverrideTarget: {}",
1802 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001803 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001804 "BootSourceTargetOverride");
1805 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001806 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301807
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001808 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001809 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1810 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001811
George Liu9ae226f2023-06-21 17:56:46 +08001812 sdbusplus::asio::setProperty(
1813 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1814 "/xyz/openbmc_project/control/host0/boot",
1815 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001816 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001817 if (ec)
1818 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001819 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001820 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001821 return;
1822 }
Ed Tanous62598e32023-07-17 17:06:25 -07001823 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001824 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001825
George Liu9ae226f2023-06-21 17:56:46 +08001826 sdbusplus::asio::setProperty(
1827 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1828 "/xyz/openbmc_project/control/host0/boot",
1829 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001830 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001831 if (ec)
1832 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001833 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001834 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001835 return;
1836 }
Ed Tanous62598e32023-07-17 17:06:25 -07001837 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001838 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001839}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001840
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001841/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001842 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301843 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001844 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301845 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001846 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301847 * @param[in] bootEnable The boot override enable from incoming RF request.
1848 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001849 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301850 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001851
Ed Tanousac106bf2023-06-07 09:24:59 -07001852inline void
1853 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1854 const std::optional<std::string>& bootSource,
1855 const std::optional<std::string>& bootType,
1856 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301857{
Ed Tanous62598e32023-07-17 17:06:25 -07001858 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301859
Ed Tanousac106bf2023-06-07 09:24:59 -07001860 setBootModeOrSource(asyncResp, bootSource);
1861 setBootType(asyncResp, bootType);
1862 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301863}
1864
George Liuc6a620f2020-04-10 17:18:11 +08001865/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001866 * @brief Sets AssetTag
1867 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001868 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001869 * @param[in] assetTag "AssetTag" from request.
1870 *
1871 * @return None.
1872 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001873inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001874 const std::string& assetTag)
1875{
George Liue99073f2022-12-09 11:06:16 +08001876 constexpr std::array<std::string_view, 1> interfaces = {
1877 "xyz.openbmc_project.Inventory.Item.System"};
1878 dbus::utility::getSubTree(
1879 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001880 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001881 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001882 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001883 if (ec)
1884 {
Ed Tanous62598e32023-07-17 17:06:25 -07001885 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001886 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001887 return;
1888 }
1889 if (subtree.empty())
1890 {
Ed Tanous62598e32023-07-17 17:06:25 -07001891 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001892 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001893 return;
1894 }
1895 // Assume only 1 system D-Bus object
1896 // Throw an error if there is more than 1
1897 if (subtree.size() > 1)
1898 {
Ed Tanous62598e32023-07-17 17:06:25 -07001899 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001900 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001901 return;
1902 }
1903 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1904 {
Ed Tanous62598e32023-07-17 17:06:25 -07001905 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001906 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001907 return;
1908 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001909
Ed Tanous002d39b2022-05-31 08:59:27 -07001910 const std::string& path = subtree[0].first;
1911 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001912
Ed Tanous002d39b2022-05-31 08:59:27 -07001913 if (service.empty())
1914 {
Ed Tanous62598e32023-07-17 17:06:25 -07001915 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001916 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001917 return;
1918 }
1919
George Liu9ae226f2023-06-21 17:56:46 +08001920 sdbusplus::asio::setProperty(
1921 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001922 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001923 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001924 if (ec2)
1925 {
1926 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1927 ec2);
1928 messages::internalError(asyncResp->res);
1929 return;
1930 }
George Liue99073f2022-12-09 11:06:16 +08001931 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001932 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001933}
1934
1935/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001936 * @brief Validate the specified stopBootOnFault is valid and return the
1937 * stopBootOnFault name associated with that string
1938 *
1939 * @param[in] stopBootOnFaultString String representing the desired
1940 * stopBootOnFault
1941 *
1942 * @return stopBootOnFault value or empty if incoming value is not valid
1943 */
1944inline std::optional<bool>
1945 validstopBootOnFault(const std::string& stopBootOnFaultString)
1946{
1947 if (stopBootOnFaultString == "AnyFault")
1948 {
1949 return true;
1950 }
1951
1952 if (stopBootOnFaultString == "Never")
1953 {
1954 return false;
1955 }
1956
1957 return std::nullopt;
1958}
1959
1960/**
1961 * @brief Sets stopBootOnFault
1962 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001963 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001964 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1965 *
1966 * @return None.
1967 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001968inline void
1969 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1970 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001971{
Ed Tanous62598e32023-07-17 17:06:25 -07001972 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001973
1974 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1975 if (!stopBootEnabled)
1976 {
Ed Tanous62598e32023-07-17 17:06:25 -07001977 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1978 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001979 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001980 "StopBootOnFault");
1981 return;
1982 }
1983
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001984 sdbusplus::asio::setProperty(
1985 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1986 "/xyz/openbmc_project/logging/settings",
1987 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1988 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001989 if (ec)
1990 {
1991 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001992 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001993 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1994 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001995 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001996 return;
1997 }
1998 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001999}
2000
2001/**
Gunnar Mills69f35302020-05-17 16:06:31 -05002002 * @brief Sets automaticRetry (Auto Reboot)
2003 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002004 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05002005 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
2006 *
2007 * @return None.
2008 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002009inline void
2010 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2011 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05002012{
Ed Tanous62598e32023-07-17 17:06:25 -07002013 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05002014
2015 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002016 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002017
2018 if (automaticRetryConfig == "Disabled")
2019 {
2020 autoRebootEnabled = false;
2021 }
2022 else if (automaticRetryConfig == "RetryAttempts")
2023 {
2024 autoRebootEnabled = true;
2025 }
2026 else
2027 {
Ed Tanous62598e32023-07-17 17:06:25 -07002028 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
2029 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07002030 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002031 "AutomaticRetryConfig");
2032 return;
2033 }
2034
George Liu9ae226f2023-06-21 17:56:46 +08002035 sdbusplus::asio::setProperty(
2036 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002037 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002038 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002039 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002040 if (ec)
2041 {
2042 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2043 messages::internalError(asyncResp->res);
2044 return;
2045 }
2046 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002047}
2048
Ed Tanous8d69c662023-06-21 10:29:06 -07002049inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2050{
2051 if (policy == "AlwaysOn")
2052 {
2053 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2054 }
2055 if (policy == "AlwaysOff")
2056 {
2057 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2058 }
2059 if (policy == "LastState")
2060 {
2061 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2062 }
2063 return "";
2064}
2065
Gunnar Mills69f35302020-05-17 16:06:31 -05002066/**
George Liuc6a620f2020-04-10 17:18:11 +08002067 * @brief Sets power restore policy properties.
2068 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002069 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002070 * @param[in] policy power restore policy properties from request.
2071 *
2072 * @return None.
2073 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002074inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002075 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002076 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002077{
Ed Tanous62598e32023-07-17 17:06:25 -07002078 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002079
Ed Tanous8d69c662023-06-21 10:29:06 -07002080 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002081
Ed Tanous8d69c662023-06-21 10:29:06 -07002082 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002083 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002084 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002085 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002086 return;
2087 }
2088
George Liu9ae226f2023-06-21 17:56:46 +08002089 sdbusplus::asio::setProperty(
2090 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002091 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002092 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002093 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002094 if (ec)
2095 {
2096 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2097 messages::internalError(asyncResp->res);
2098 return;
2099 }
2100 });
George Liuc6a620f2020-04-10 17:18:11 +08002101}
2102
AppaRao Pulia6349912019-10-18 17:16:08 +05302103#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2104/**
2105 * @brief Retrieves provisioning status
2106 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002107 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302108 *
2109 * @return None.
2110 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002111inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302112{
Ed Tanous62598e32023-07-17 17:06:25 -07002113 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002114 sdbusplus::asio::getAllProperties(
2115 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2116 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002117 [asyncResp](const boost::system::error_code& ec,
2118 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002119 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002120 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2121 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002122 "#OemComputerSystem.OpenBmc";
2123 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002124
Ed Tanous002d39b2022-05-31 08:59:27 -07002125 if (ec)
2126 {
Ed Tanous62598e32023-07-17 17:06:25 -07002127 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002128 // not an error, don't have to have the interface
2129 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2130 return;
2131 }
2132
2133 const bool* provState = nullptr;
2134 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002135
2136 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002137 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2138 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002139
2140 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002141 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002142 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002143 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002144 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302145
Ed Tanous002d39b2022-05-31 08:59:27 -07002146 if ((provState == nullptr) || (lockState == nullptr))
2147 {
Ed Tanous62598e32023-07-17 17:06:25 -07002148 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002149 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002150 return;
2151 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302152
Ed Tanous002d39b2022-05-31 08:59:27 -07002153 if (*provState == true)
2154 {
2155 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302156 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002157 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302158 }
2159 else
2160 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002161 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302162 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002163 }
2164 else
2165 {
2166 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2167 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002168 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302169}
2170#endif
2171
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302172/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002173 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002174 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002175 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002176 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002177 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002178 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002179inline computer_system::PowerMode
2180 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002181{
Chris Cainb6655102024-02-01 14:35:33 -06002182 using PowerMode = computer_system::PowerMode;
2183
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002184 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002185 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002186 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002187 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002188 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002189 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002190 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002191 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002192 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002193 if (modeString ==
2194 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002195 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002196 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002197 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002198 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002199 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2200 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002201 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002202 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002203 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002204 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2205 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002206 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002207 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002208 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002209 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2210 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002211 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002212 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002213 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002214 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002215 return PowerMode::OEM;
2216 }
2217 // Any other values would be invalid
2218 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2219 return PowerMode::Invalid;
2220}
2221
2222inline void
2223 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2224 const boost::system::error_code& ec,
2225 const dbus::utility::DBusPropertiesMap& properties)
2226{
2227 if (ec)
2228 {
2229 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2230 messages::internalError(asyncResp->res);
2231 return;
2232 }
2233
2234 std::string powerMode;
2235 const std::vector<std::string>* allowedModes = nullptr;
2236 const bool success = sdbusplus::unpackPropertiesNoThrow(
2237 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2238 "AllowedPowerModes", allowedModes);
2239
2240 if (!success)
2241 {
2242 messages::internalError(asyncResp->res);
2243 return;
2244 }
2245
2246 nlohmann::json::array_t modeList;
2247 if (allowedModes == nullptr)
2248 {
2249 modeList.emplace_back("Static");
2250 modeList.emplace_back("MaximumPerformance");
2251 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002252 }
2253 else
2254 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002255 for (const auto& aMode : *allowedModes)
2256 {
2257 computer_system::PowerMode modeValue =
2258 translatePowerModeString(aMode);
2259 if (modeValue == computer_system::PowerMode::Invalid)
2260 {
2261 messages::internalError(asyncResp->res);
2262 continue;
2263 }
2264 modeList.emplace_back(modeValue);
2265 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002266 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002267 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002268
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002269 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2270 const computer_system::PowerMode modeValue =
2271 translatePowerModeString(powerMode);
2272 if (modeValue == computer_system::PowerMode::Invalid)
2273 {
2274 messages::internalError(asyncResp->res);
2275 return;
2276 }
2277 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2278}
Chris Cain3a2d04242021-05-28 16:57:10 -05002279/**
2280 * @brief Retrieves system power mode
2281 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002283 *
2284 * @return None.
2285 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002286inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002287{
Ed Tanous62598e32023-07-17 17:06:25 -07002288 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002289
2290 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002291 constexpr std::array<std::string_view, 1> interfaces = {
2292 "xyz.openbmc_project.Control.Power.Mode"};
2293 dbus::utility::getSubTree(
2294 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002295 [asyncResp](const boost::system::error_code& ec,
2296 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002297 if (ec)
2298 {
Ed Tanous62598e32023-07-17 17:06:25 -07002299 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2300 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002301 // This is an optional D-Bus object so just return if
2302 // error occurs
2303 return;
2304 }
2305 if (subtree.empty())
2306 {
2307 // As noted above, this is an optional interface so just return
2308 // if there is no instance found
2309 return;
2310 }
2311 if (subtree.size() > 1)
2312 {
2313 // More then one PowerMode object is not supported and is an
2314 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002315 BMCWEB_LOG_DEBUG(
2316 "Found more than 1 system D-Bus Power.Mode objects: {}",
2317 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002318 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002319 return;
2320 }
2321 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2322 {
Ed Tanous62598e32023-07-17 17:06:25 -07002323 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002324 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002325 return;
2326 }
2327 const std::string& path = subtree[0].first;
2328 const std::string& service = subtree[0].second.begin()->first;
2329 if (service.empty())
2330 {
Ed Tanous62598e32023-07-17 17:06:25 -07002331 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002332 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002333 return;
2334 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002335
2336 // Valid Power Mode object found, now read the mode properties
2337 sdbusplus::asio::getAllProperties(
Ed Tanous002d39b2022-05-31 08:59:27 -07002338 *crow::connections::systemBus, service, path,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002339 "xyz.openbmc_project.Control.Power.Mode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002340 [asyncResp](const boost::system::error_code& ec2,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002341 const dbus::utility::DBusPropertiesMap& properties) {
2342 afterGetPowerMode(asyncResp, ec2, properties);
George Liue99073f2022-12-09 11:06:16 +08002343 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002344 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002345}
2346
2347/**
2348 * @brief Validate the specified mode is valid and return the PowerMode
2349 * name associated with that string
2350 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002351 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002352 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002353 *
2354 * @return PowerMode value or empty string if mode is not valid
2355 */
2356inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002357 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002358 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002359{
Chris Cainb6655102024-02-01 14:35:33 -06002360 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002361 std::string mode;
2362
Chris Cainb6655102024-02-01 14:35:33 -06002363 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002364 {
2365 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2366 }
Chris Cainb6655102024-02-01 14:35:33 -06002367 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002368 {
George Liu0fda0f12021-11-16 10:06:17 +08002369 mode =
2370 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002371 }
Chris Cainb6655102024-02-01 14:35:33 -06002372 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002373 {
2374 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2375 }
Chris Cainb6655102024-02-01 14:35:33 -06002376 else if (modeValue == PowerMode::BalancedPerformance)
2377 {
2378 mode =
2379 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2380 }
2381 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2382 {
2383 mode =
2384 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2385 }
2386 else if (modeValue == PowerMode::EfficiencyFavorPower)
2387 {
2388 mode =
2389 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2390 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002391 else
2392 {
Chris Cainb6655102024-02-01 14:35:33 -06002393 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002394 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002395 }
2396 return mode;
2397}
2398
2399/**
2400 * @brief Sets system power mode.
2401 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002402 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002403 * @param[in] pmode System power mode from request.
2404 *
2405 * @return None.
2406 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002407inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002408 const std::string& pmode)
2409{
Ed Tanous62598e32023-07-17 17:06:25 -07002410 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002411
Ed Tanousac106bf2023-06-07 09:24:59 -07002412 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002413 if (powerMode.empty())
2414 {
2415 return;
2416 }
2417
2418 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002419 constexpr std::array<std::string_view, 1> interfaces = {
2420 "xyz.openbmc_project.Control.Power.Mode"};
2421 dbus::utility::getSubTree(
2422 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002423 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002424 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002425 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002426 if (ec)
2427 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002428 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002429 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002430 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002431 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002432 return;
2433 }
2434 if (subtree.empty())
2435 {
2436 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002437 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002438 "PowerMode");
2439 return;
2440 }
2441 if (subtree.size() > 1)
2442 {
2443 // More then one PowerMode object is not supported and is an
2444 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002445 BMCWEB_LOG_DEBUG(
2446 "Found more than 1 system D-Bus Power.Mode objects: {}",
2447 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002448 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002449 return;
2450 }
2451 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2452 {
Ed Tanous62598e32023-07-17 17:06:25 -07002453 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002454 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002455 return;
2456 }
2457 const std::string& path = subtree[0].first;
2458 const std::string& service = subtree[0].second.begin()->first;
2459 if (service.empty())
2460 {
Ed Tanous62598e32023-07-17 17:06:25 -07002461 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002462 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002463 return;
2464 }
2465
Ed Tanous62598e32023-07-17 17:06:25 -07002466 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002467
2468 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002469 sdbusplus::asio::setProperty(
2470 *crow::connections::systemBus, service, path,
2471 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002472 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002473 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002474 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002475 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002476 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002477 return;
2478 }
George Liue99073f2022-12-09 11:06:16 +08002479 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002480 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002481}
2482
2483/**
Yong Li51709ff2019-09-30 14:13:04 +08002484 * @brief Translates watchdog timeout action DBUS property value to redfish.
2485 *
2486 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2487 *
2488 * @return Returns as a string, the timeout action in Redfish terms. If
2489 * translation cannot be done, returns an empty string.
2490 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002491inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002492{
2493 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2494 {
2495 return "None";
2496 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002497 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002498 {
2499 return "ResetSystem";
2500 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002501 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002502 {
2503 return "PowerDown";
2504 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002505 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002506 {
2507 return "PowerCycle";
2508 }
2509
2510 return "";
2511}
2512
2513/**
Yong Lic45f0082019-10-10 14:19:01 +08002514 *@brief Translates timeout action from Redfish to DBUS property value.
2515 *
2516 *@param[in] rfAction The timeout action in Redfish.
2517 *
2518 *@return Returns as a string, the time_out action as expected by DBUS.
2519 *If translation cannot be done, returns an empty string.
2520 */
2521
Ed Tanous23a21a12020-07-25 04:45:05 +00002522inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002523{
2524 if (rfAction == "None")
2525 {
2526 return "xyz.openbmc_project.State.Watchdog.Action.None";
2527 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002528 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002529 {
2530 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2531 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002532 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002533 {
2534 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2535 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002536 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002537 {
2538 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2539 }
2540
2541 return "";
2542}
2543
2544/**
Yong Li51709ff2019-09-30 14:13:04 +08002545 * @brief Retrieves host watchdog timer properties over DBUS
2546 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002547 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002548 *
2549 * @return None.
2550 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002551inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002552 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002553{
Ed Tanous62598e32023-07-17 17:06:25 -07002554 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002555 sdbusplus::asio::getAllProperties(
2556 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2557 "/xyz/openbmc_project/watchdog/host0",
2558 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002559 [asyncResp](const boost::system::error_code& ec,
2560 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002561 if (ec)
2562 {
2563 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002564 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002565 return;
2566 }
2567
Ed Tanous62598e32023-07-17 17:06:25 -07002568 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002569
2570 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002571 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002572
2573 // watchdog service is running/enabled
2574 hostWatchdogTimer["Status"]["State"] = "Enabled";
2575
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002576 const bool* enabled = nullptr;
2577 const std::string* expireAction = nullptr;
2578
2579 const bool success = sdbusplus::unpackPropertiesNoThrow(
2580 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2581 "ExpireAction", expireAction);
2582
2583 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002584 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002585 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002586 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002587 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002588
2589 if (enabled != nullptr)
2590 {
2591 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2592 }
2593
2594 if (expireAction != nullptr)
2595 {
2596 std::string action = dbusToRfWatchdogAction(*expireAction);
2597 if (action.empty())
2598 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002599 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002600 return;
2601 }
2602 hostWatchdogTimer["TimeoutAction"] = action;
2603 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002604 });
Yong Li51709ff2019-09-30 14:13:04 +08002605}
2606
2607/**
Yong Lic45f0082019-10-10 14:19:01 +08002608 * @brief Sets Host WatchDog Timer properties.
2609 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002610 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002611 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2612 * RF request.
2613 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2614 *
2615 * @return None.
2616 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002617inline void
2618 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2619 const std::optional<bool> wdtEnable,
2620 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002621{
Ed Tanous62598e32023-07-17 17:06:25 -07002622 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002623
2624 if (wdtTimeOutAction)
2625 {
2626 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2627 // check if TimeOut Action is Valid
2628 if (wdtTimeOutActStr.empty())
2629 {
Ed Tanous62598e32023-07-17 17:06:25 -07002630 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2631 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002632 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002633 "TimeoutAction");
2634 return;
2635 }
2636
George Liu9ae226f2023-06-21 17:56:46 +08002637 sdbusplus::asio::setProperty(
2638 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002639 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002640 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002641 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002642 if (ec)
2643 {
2644 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2645 messages::internalError(asyncResp->res);
2646 return;
2647 }
2648 });
Yong Lic45f0082019-10-10 14:19:01 +08002649 }
2650
2651 if (wdtEnable)
2652 {
George Liu9ae226f2023-06-21 17:56:46 +08002653 sdbusplus::asio::setProperty(
2654 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2655 "/xyz/openbmc_project/watchdog/host0",
2656 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002657 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002658 if (ec)
2659 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002660 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002661 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002662 return;
2663 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002664 });
Yong Lic45f0082019-10-10 14:19:01 +08002665 }
2666}
2667
Chris Cain37bbf982021-09-20 10:53:09 -05002668/**
2669 * @brief Parse the Idle Power Saver properties into json
2670 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002671 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002672 * @param[in] properties IPS property data from DBus.
2673 *
2674 * @return true if successful
2675 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002676inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002677 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002678 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002679{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002680 const bool* enabled = nullptr;
2681 const uint8_t* enterUtilizationPercent = nullptr;
2682 const uint64_t* enterDwellTime = nullptr;
2683 const uint8_t* exitUtilizationPercent = nullptr;
2684 const uint64_t* exitDwellTime = nullptr;
2685
2686 const bool success = sdbusplus::unpackPropertiesNoThrow(
2687 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002688 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2689 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2690 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002691
2692 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002693 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002694 return false;
2695 }
2696
2697 if (enabled != nullptr)
2698 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002699 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002700 }
2701
2702 if (enterUtilizationPercent != nullptr)
2703 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002704 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002705 *enterUtilizationPercent;
2706 }
2707
2708 if (enterDwellTime != nullptr)
2709 {
2710 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002711 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002712 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2713 .count();
2714 }
2715
2716 if (exitUtilizationPercent != nullptr)
2717 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002718 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002719 *exitUtilizationPercent;
2720 }
2721
2722 if (exitDwellTime != nullptr)
2723 {
2724 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002725 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002726 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2727 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002728 }
2729
2730 return true;
2731}
2732
2733/**
2734 * @brief Retrieves host watchdog timer properties over DBUS
2735 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002736 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002737 *
2738 * @return None.
2739 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002740inline void
2741 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002742{
Ed Tanous62598e32023-07-17 17:06:25 -07002743 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002744
2745 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002746 constexpr std::array<std::string_view, 1> interfaces = {
2747 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2748 dbus::utility::getSubTree(
2749 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002750 [asyncResp](const boost::system::error_code& ec,
2751 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002752 if (ec)
2753 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002754 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002755 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2756 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002757 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002758 return;
2759 }
2760 if (subtree.empty())
2761 {
2762 // This is an optional interface so just return
2763 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002764 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002765 return;
2766 }
2767 if (subtree.size() > 1)
2768 {
2769 // More then one PowerIdlePowerSaver object is not supported and
2770 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002771 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2772 "Power.IdlePowerSaver objects: {}",
2773 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002774 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002775 return;
2776 }
2777 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2778 {
Ed Tanous62598e32023-07-17 17:06:25 -07002779 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002780 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002781 return;
2782 }
2783 const std::string& path = subtree[0].first;
2784 const std::string& service = subtree[0].second.begin()->first;
2785 if (service.empty())
2786 {
Ed Tanous62598e32023-07-17 17:06:25 -07002787 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002788 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002789 return;
2790 }
2791
2792 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002793 sdbusplus::asio::getAllProperties(
2794 *crow::connections::systemBus, service, path,
2795 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002796 [asyncResp](const boost::system::error_code& ec2,
2797 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002798 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002799 {
Ed Tanous62598e32023-07-17 17:06:25 -07002800 BMCWEB_LOG_ERROR(
2801 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002802 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002803 return;
2804 }
2805
Ed Tanousac106bf2023-06-07 09:24:59 -07002806 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002807 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002808 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002809 return;
2810 }
George Liue99073f2022-12-09 11:06:16 +08002811 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002812 });
Chris Cain37bbf982021-09-20 10:53:09 -05002813
Ed Tanous62598e32023-07-17 17:06:25 -07002814 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002815}
2816
2817/**
2818 * @brief Sets Idle Power Saver properties.
2819 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002820 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002821 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2822 * RF request.
2823 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2824 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2825 * before entering idle state.
2826 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2827 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2828 * before exiting idle state
2829 *
2830 * @return None.
2831 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002832inline void
2833 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2834 const std::optional<bool> ipsEnable,
2835 const std::optional<uint8_t> ipsEnterUtil,
2836 const std::optional<uint64_t> ipsEnterTime,
2837 const std::optional<uint8_t> ipsExitUtil,
2838 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002839{
Ed Tanous62598e32023-07-17 17:06:25 -07002840 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002841
2842 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002843 constexpr std::array<std::string_view, 1> interfaces = {
2844 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2845 dbus::utility::getSubTree(
2846 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002847 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002848 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002849 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002850 if (ec)
2851 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002852 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002853 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2854 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002855 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002856 return;
2857 }
2858 if (subtree.empty())
2859 {
2860 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002861 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002862 "IdlePowerSaver");
2863 return;
2864 }
2865 if (subtree.size() > 1)
2866 {
2867 // More then one PowerIdlePowerSaver object is not supported and
2868 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002869 BMCWEB_LOG_DEBUG(
2870 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2871 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002872 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002873 return;
2874 }
2875 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2876 {
Ed Tanous62598e32023-07-17 17:06:25 -07002877 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002878 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002879 return;
2880 }
2881 const std::string& path = subtree[0].first;
2882 const std::string& service = subtree[0].second.begin()->first;
2883 if (service.empty())
2884 {
Ed Tanous62598e32023-07-17 17:06:25 -07002885 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002886 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002887 return;
2888 }
Chris Cain37bbf982021-09-20 10:53:09 -05002889
Ed Tanous002d39b2022-05-31 08:59:27 -07002890 // Valid Power IdlePowerSaver object found, now set any values that
2891 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002892
Ed Tanous002d39b2022-05-31 08:59:27 -07002893 if (ipsEnable)
2894 {
George Liu9ae226f2023-06-21 17:56:46 +08002895 sdbusplus::asio::setProperty(
2896 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002897 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002898 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002899 if (ec2)
2900 {
2901 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2902 messages::internalError(asyncResp->res);
2903 return;
2904 }
2905 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002906 }
2907 if (ipsEnterUtil)
2908 {
George Liu9ae226f2023-06-21 17:56:46 +08002909 sdbusplus::asio::setProperty(
2910 *crow::connections::systemBus, service, path,
2911 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2912 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002913 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002914 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002915 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002916 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002917 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002918 return;
2919 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002920 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002921 }
2922 if (ipsEnterTime)
2923 {
2924 // Convert from seconds into milliseconds for DBus
2925 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002926 sdbusplus::asio::setProperty(
2927 *crow::connections::systemBus, service, path,
2928 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2929 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002930 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002931 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002932 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002933 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002934 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002935 return;
2936 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002937 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002938 }
2939 if (ipsExitUtil)
2940 {
George Liu9ae226f2023-06-21 17:56:46 +08002941 sdbusplus::asio::setProperty(
2942 *crow::connections::systemBus, service, path,
2943 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2944 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002945 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002946 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002947 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002948 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002949 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002950 return;
2951 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002952 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002953 }
2954 if (ipsExitTime)
2955 {
2956 // Convert from seconds into milliseconds for DBus
2957 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002958 sdbusplus::asio::setProperty(
2959 *crow::connections::systemBus, service, path,
2960 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2961 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002962 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002963 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002964 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002965 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002966 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002967 return;
2968 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002969 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002970 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002971 });
Chris Cain37bbf982021-09-20 10:53:09 -05002972
Ed Tanous62598e32023-07-17 17:06:25 -07002973 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002974}
2975
Ed Tanousc1e219d2023-06-07 10:34:33 -07002976inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002977 crow::App& app, const crow::Request& req,
2978 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2979{
2980 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2981 {
2982 return;
2983 }
2984 asyncResp->res.addHeader(
2985 boost::beast::http::field::link,
2986 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2987}
2988
Ed Tanousc1e219d2023-06-07 10:34:33 -07002989inline void handleComputerSystemCollectionGet(
2990 crow::App& app, const crow::Request& req,
2991 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2992{
2993 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2994 {
2995 return;
2996 }
2997
2998 asyncResp->res.addHeader(
2999 boost::beast::http::field::link,
3000 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
3001 asyncResp->res.jsonValue["@odata.type"] =
3002 "#ComputerSystemCollection.ComputerSystemCollection";
3003 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
3004 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
3005
3006 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
3007 ifaceArray = nlohmann::json::array();
3008 if constexpr (bmcwebEnableMultiHost)
3009 {
3010 asyncResp->res.jsonValue["Members@odata.count"] = 0;
3011 // Option currently returns no systems. TBD
3012 return;
3013 }
3014 asyncResp->res.jsonValue["Members@odata.count"] = 1;
3015 nlohmann::json::object_t system;
3016 system["@odata.id"] = "/redfish/v1/Systems/system";
3017 ifaceArray.emplace_back(std::move(system));
3018 sdbusplus::asio::getProperty<std::string>(
3019 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
3020 "/xyz/openbmc_project/network/hypervisor",
3021 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
3022 [asyncResp](const boost::system::error_code& ec2,
3023 const std::string& /*hostName*/) {
3024 if (ec2)
3025 {
3026 return;
3027 }
3028 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
3029 if (val == asyncResp->res.jsonValue.end())
3030 {
Ed Tanous62598e32023-07-17 17:06:25 -07003031 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003032 return;
3033 }
3034 uint64_t* count = val->get_ptr<uint64_t*>();
3035 if (count == nullptr)
3036 {
Ed Tanous62598e32023-07-17 17:06:25 -07003037 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003038 return;
3039 }
3040 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07003041 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003042 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
3043 nlohmann::json::object_t hypervisor;
3044 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
3045 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05003046 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003047}
3048
Yong Lic45f0082019-10-10 14:19:01 +08003049/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003050 * Function transceives data with dbus directly.
3051 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07003052inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003053{
Patrick Williams89492a12023-05-10 07:51:34 -05003054 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
3055 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
3056 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003057 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05003058 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003059
3060 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08003061 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07003062 if (ec)
3063 {
Ed Tanous62598e32023-07-17 17:06:25 -07003064 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07003065 messages::internalError(asyncResp->res);
3066 return;
3067 }
3068 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003069 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003070 serviceName, objectPath, interfaceName, method);
3071}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003072
Ed Tanousc1e219d2023-06-07 10:34:33 -07003073inline void handleComputerSystemResetActionPost(
3074 crow::App& app, const crow::Request& req,
3075 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3076 const std::string& systemName)
3077{
3078 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3079 {
3080 return;
3081 }
3082 if (systemName != "system")
3083 {
3084 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3085 systemName);
3086 return;
3087 }
3088 if constexpr (bmcwebEnableMultiHost)
3089 {
3090 // Option currently returns no systems. TBD
3091 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3092 systemName);
3093 return;
3094 }
3095 std::string resetType;
3096 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3097 {
3098 return;
3099 }
3100
3101 // Get the command and host vs. chassis
3102 std::string command;
3103 bool hostCommand = true;
3104 if ((resetType == "On") || (resetType == "ForceOn"))
3105 {
3106 command = "xyz.openbmc_project.State.Host.Transition.On";
3107 hostCommand = true;
3108 }
3109 else if (resetType == "ForceOff")
3110 {
3111 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3112 hostCommand = false;
3113 }
3114 else if (resetType == "ForceRestart")
3115 {
3116 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3117 hostCommand = true;
3118 }
3119 else if (resetType == "GracefulShutdown")
3120 {
3121 command = "xyz.openbmc_project.State.Host.Transition.Off";
3122 hostCommand = true;
3123 }
3124 else if (resetType == "GracefulRestart")
3125 {
3126 command =
3127 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3128 hostCommand = true;
3129 }
3130 else if (resetType == "PowerCycle")
3131 {
3132 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3133 hostCommand = true;
3134 }
3135 else if (resetType == "Nmi")
3136 {
3137 doNMI(asyncResp);
3138 return;
3139 }
3140 else
3141 {
3142 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3143 return;
3144 }
Ed Tanousd02aad32024-02-13 14:43:34 -08003145 sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003146
3147 if (hostCommand)
3148 {
Ed Tanousd02aad32024-02-13 14:43:34 -08003149 setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host",
3150 statePath / "host0", "xyz.openbmc_project.State.Host",
3151 "RequestedHostTransition", "Reset", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003152 }
3153 else
3154 {
Ed Tanousd02aad32024-02-13 14:43:34 -08003155 setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis",
3156 statePath / "chassis0",
3157 "xyz.openbmc_project.State.Chassis",
3158 "RequestedPowerTransition", "Reset", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003159 }
3160}
3161
Ed Tanousc1e219d2023-06-07 10:34:33 -07003162inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003163 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003164 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3165 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003166{
3167 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3168 {
3169 return;
3170 }
3171
3172 asyncResp->res.addHeader(
3173 boost::beast::http::field::link,
3174 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3175}
3176
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003177inline void afterPortRequest(
3178 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3179 const boost::system::error_code& ec,
3180 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3181{
3182 if (ec)
3183 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003184 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003185 messages::internalError(asyncResp->res);
3186 return;
3187 }
3188 for (const auto& data : socketData)
3189 {
3190 const std::string& socketPath = get<0>(data);
3191 const std::string& protocolName = get<1>(data);
3192 bool isProtocolEnabled = get<2>(data);
3193 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3194 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3195 // need to retrieve port number for
3196 // obmc-console-ssh service
3197 if (protocolName == "SSH")
3198 {
3199 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003200 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003201 int portNumber) {
3202 if (ec1)
3203 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003204 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003205 messages::internalError(asyncResp->res);
3206 return;
3207 }
3208 nlohmann::json& dataJson1 =
3209 asyncResp->res.jsonValue["SerialConsole"];
3210 dataJson1[protocolName]["Port"] = portNumber;
3211 });
3212 }
3213 }
3214}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003215
3216inline void
3217 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3218 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3219 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003220{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003221 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3222 {
3223 return;
3224 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003225
Ed Tanousc1e219d2023-06-07 10:34:33 -07003226 if constexpr (bmcwebEnableMultiHost)
3227 {
3228 // Option currently returns no systems. TBD
3229 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3230 systemName);
3231 return;
3232 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003233
Ed Tanousc1e219d2023-06-07 10:34:33 -07003234 if (systemName == "hypervisor")
3235 {
3236 handleHypervisorSystemGet(asyncResp);
3237 return;
3238 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003239
Ed Tanousc1e219d2023-06-07 10:34:33 -07003240 if (systemName != "system")
3241 {
3242 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3243 systemName);
3244 return;
3245 }
3246 asyncResp->res.addHeader(
3247 boost::beast::http::field::link,
3248 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3249 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003250 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanousc1e219d2023-06-07 10:34:33 -07003251 asyncResp->res.jsonValue["Name"] = "system";
3252 asyncResp->res.jsonValue["Id"] = "system";
3253 asyncResp->res.jsonValue["SystemType"] = "Physical";
3254 asyncResp->res.jsonValue["Description"] = "Computer System";
3255 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3256 if constexpr (bmcwebEnableProcMemStatus)
3257 {
3258 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3259 "Disabled";
3260 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3261 "Disabled";
3262 }
3263 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003264 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003265 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003266
Ed Tanousc1e219d2023-06-07 10:34:33 -07003267 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3268 "/redfish/v1/Systems/system/Processors";
3269 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3270 "/redfish/v1/Systems/system/Memory";
3271 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3272 "/redfish/v1/Systems/system/Storage";
3273 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3274 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003275
Ed Tanousc1e219d2023-06-07 10:34:33 -07003276 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3277 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3278 asyncResp->res
3279 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3280 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003281
Ed Tanousc1e219d2023-06-07 10:34:33 -07003282 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3283 "/redfish/v1/Systems/system/LogServices";
3284 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3285 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003286
Ed Tanousc1e219d2023-06-07 10:34:33 -07003287 nlohmann::json::array_t managedBy;
3288 nlohmann::json& manager = managedBy.emplace_back();
3289 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3290 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3291 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3292 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003293
Ed Tanousc1e219d2023-06-07 10:34:33 -07003294 // Fill in SerialConsole info
3295 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3296 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003297
Ed Tanousc1e219d2023-06-07 10:34:33 -07003298 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3299 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3300 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3301 "Press ~. to exit console";
3302 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3303 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003304
3305#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003306 // Fill in GraphicalConsole info
3307 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3308 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3309 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3310 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003311
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003312#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003313
Ed Tanousc1e219d2023-06-07 10:34:33 -07003314 auto health = std::make_shared<HealthPopulate>(asyncResp);
3315 if constexpr (bmcwebEnableHealthPopulate)
3316 {
3317 constexpr std::array<std::string_view, 4> inventoryForSystems{
3318 "xyz.openbmc_project.Inventory.Item.Dimm",
3319 "xyz.openbmc_project.Inventory.Item.Cpu",
3320 "xyz.openbmc_project.Inventory.Item.Drive",
3321 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003322
Ed Tanousc1e219d2023-06-07 10:34:33 -07003323 dbus::utility::getSubTreePaths(
3324 "/", 0, inventoryForSystems,
3325 [health](const boost::system::error_code& ec,
3326 const std::vector<std::string>& resp) {
3327 if (ec)
3328 {
3329 // no inventory
3330 return;
3331 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003332
Ed Tanousc1e219d2023-06-07 10:34:33 -07003333 health->inventory = resp;
Patrick Williams5a39f772023-10-20 11:20:21 -05003334 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003335 health->populate();
3336 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003337
Ed Tanousc1e219d2023-06-07 10:34:33 -07003338 getMainChassisId(asyncResp,
3339 [](const std::string& chassisId,
3340 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3341 nlohmann::json::array_t chassisArray;
3342 nlohmann::json& chassis = chassisArray.emplace_back();
3343 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3344 chassisId);
3345 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3346 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003347
George Liu59a17e42022-10-08 09:27:47 +08003348 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003349 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3350 getIndicatorLedState(asyncResp);
3351 getComputerSystem(asyncResp, health);
3352 getHostState(asyncResp);
3353 getBootProperties(asyncResp);
3354 getBootProgress(asyncResp);
3355 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003356 pcie_util::getPCIeDeviceList(asyncResp,
3357 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003358 getHostWatchdogTimer(asyncResp);
3359 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003360 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003361 getAutomaticRetryPolicy(asyncResp);
3362 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003363#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003364 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003365#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003366 getTrustedModuleRequiredToBoot(asyncResp);
3367 getPowerMode(asyncResp);
3368 getIdlePowerSaver(asyncResp);
3369}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003370
Ed Tanousc1e219d2023-06-07 10:34:33 -07003371inline void handleComputerSystemPatch(
3372 crow::App& app, const crow::Request& req,
3373 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3374 const std::string& systemName)
3375{
3376 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3377 {
3378 return;
3379 }
3380 if constexpr (bmcwebEnableMultiHost)
3381 {
3382 // Option currently returns no systems. TBD
3383 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3384 systemName);
3385 return;
3386 }
3387 if (systemName != "system")
3388 {
3389 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3390 systemName);
3391 return;
3392 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003393
Ed Tanousc1e219d2023-06-07 10:34:33 -07003394 asyncResp->res.addHeader(
3395 boost::beast::http::field::link,
3396 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003397
Ed Tanousc1e219d2023-06-07 10:34:33 -07003398 std::optional<bool> locationIndicatorActive;
3399 std::optional<std::string> indicatorLed;
3400 std::optional<std::string> assetTag;
3401 std::optional<std::string> powerRestorePolicy;
3402 std::optional<std::string> powerMode;
3403 std::optional<bool> wdtEnable;
3404 std::optional<std::string> wdtTimeOutAction;
3405 std::optional<std::string> bootSource;
3406 std::optional<std::string> bootType;
3407 std::optional<std::string> bootEnable;
3408 std::optional<std::string> bootAutomaticRetry;
3409 std::optional<uint32_t> bootAutomaticRetryAttempts;
3410 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003411 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003412 std::optional<bool> ipsEnable;
3413 std::optional<uint8_t> ipsEnterUtil;
3414 std::optional<uint64_t> ipsEnterTime;
3415 std::optional<uint8_t> ipsExitUtil;
3416 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003417
Ed Tanousc1e219d2023-06-07 10:34:33 -07003418 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003419 if (!json_util::readJsonPatch(
3420 req, asyncResp->res,
3421 "IndicatorLED", indicatorLed,
3422 "LocationIndicatorActive", locationIndicatorActive,
3423 "AssetTag", assetTag,
3424 "PowerRestorePolicy", powerRestorePolicy,
3425 "PowerMode", powerMode,
3426 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3427 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3428 "Boot/BootSourceOverrideTarget", bootSource,
3429 "Boot/BootSourceOverrideMode", bootType,
3430 "Boot/BootSourceOverrideEnabled", bootEnable,
3431 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003432 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003433 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003434 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003435 "IdlePowerSaver/Enabled", ipsEnable,
3436 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3437 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3438 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3439 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3440 {
3441 return;
3442 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003443 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003444
Ed Tanousc1e219d2023-06-07 10:34:33 -07003445 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003446
Ed Tanousc1e219d2023-06-07 10:34:33 -07003447 if (assetTag)
3448 {
3449 setAssetTag(asyncResp, *assetTag);
3450 }
James Feistb49ac872019-05-21 15:12:01 -07003451
Ed Tanousc1e219d2023-06-07 10:34:33 -07003452 if (wdtEnable || wdtTimeOutAction)
3453 {
3454 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3455 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003456
Ed Tanousc1e219d2023-06-07 10:34:33 -07003457 if (bootSource || bootType || bootEnable)
3458 {
3459 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3460 }
3461 if (bootAutomaticRetry)
3462 {
3463 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3464 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003465
Ed Tanousc1e219d2023-06-07 10:34:33 -07003466 if (bootAutomaticRetryAttempts)
3467 {
3468 setAutomaticRetryAttempts(asyncResp,
3469 bootAutomaticRetryAttempts.value());
3470 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003471
Ed Tanousc1e219d2023-06-07 10:34:33 -07003472 if (bootTrustedModuleRequired)
3473 {
3474 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3475 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003476
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003477 if (stopBootOnFault)
3478 {
3479 setStopBootOnFault(asyncResp, *stopBootOnFault);
3480 }
3481
Ed Tanousc1e219d2023-06-07 10:34:33 -07003482 if (locationIndicatorActive)
3483 {
George Liu59a17e42022-10-08 09:27:47 +08003484 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003485 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003486
Ed Tanousc1e219d2023-06-07 10:34:33 -07003487 // TODO (Gunnar): Remove IndicatorLED after enough time has
3488 // passed
3489 if (indicatorLed)
3490 {
3491 setIndicatorLedState(asyncResp, *indicatorLed);
3492 asyncResp->res.addHeader(boost::beast::http::field::warning,
3493 "299 - \"IndicatorLED is deprecated. Use "
3494 "LocationIndicatorActive instead.\"");
3495 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003496
Ed Tanousc1e219d2023-06-07 10:34:33 -07003497 if (powerRestorePolicy)
3498 {
3499 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3500 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003501
Ed Tanousc1e219d2023-06-07 10:34:33 -07003502 if (powerMode)
3503 {
3504 setPowerMode(asyncResp, *powerMode);
3505 }
Chris Cain37bbf982021-09-20 10:53:09 -05003506
Ed Tanousc1e219d2023-06-07 10:34:33 -07003507 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3508 {
3509 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3510 ipsExitUtil, ipsExitTime);
3511 }
3512}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303513
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003514inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003515 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003516 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003517 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003518{
3519 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3520 {
3521 return;
3522 }
3523 asyncResp->res.addHeader(
3524 boost::beast::http::field::link,
3525 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3526}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003527
3528/**
3529 * @brief Translates allowed host transitions to redfish string
3530 *
3531 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3532 * @param[out] allowableValues The translated host transition(s)
3533 *
3534 * @return Emplaces correpsonding Redfish translated value(s) in
3535 * allowableValues. If translation not possible, does nothing to
3536 * allowableValues.
3537 */
3538inline void
3539 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3540 nlohmann::json::array_t& allowableValues)
3541{
3542 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3543 {
3544 allowableValues.emplace_back(resource::ResetType::On);
3545 allowableValues.emplace_back(resource::ResetType::ForceOn);
3546 }
3547 else if (dbusAllowedHostTran ==
3548 "xyz.openbmc_project.State.Host.Transition.Off")
3549 {
3550 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3551 }
3552 else if (dbusAllowedHostTran ==
3553 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3554 {
3555 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3556 }
3557 else if (dbusAllowedHostTran ==
3558 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3559 {
3560 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3561 }
3562 else
3563 {
3564 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3565 }
3566}
3567
3568inline void afterGetAllowedHostTransitions(
3569 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3570 const boost::system::error_code& ec,
3571 const std::vector<std::string>& allowedHostTransitions)
3572{
3573 nlohmann::json::array_t allowableValues;
3574
3575 // Supported on all systems currently
3576 allowableValues.emplace_back(resource::ResetType::ForceOff);
3577 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3578 allowableValues.emplace_back(resource::ResetType::Nmi);
3579
3580 if (ec)
3581 {
Ed Tanouse715d142024-03-07 15:47:37 -08003582 if ((ec.value() ==
3583 boost::system::linux_error::bad_request_descriptor) ||
3584 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003585 {
3586 // Property not implemented so just return defaults
3587 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3588 allowableValues.emplace_back(resource::ResetType::On);
3589 allowableValues.emplace_back(resource::ResetType::ForceOn);
3590 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3591 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3592 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3593 }
3594 else
3595 {
3596 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3597 messages::internalError(asyncResp->res);
3598 return;
3599 }
3600 }
3601 else
3602 {
3603 for (const std::string& transition : allowedHostTransitions)
3604 {
3605 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3606 dbusToRfAllowedHostTransitions(transition, allowableValues);
3607 }
3608 }
3609
3610 nlohmann::json::object_t parameter;
3611 parameter["Name"] = "ResetType";
3612 parameter["Required"] = true;
3613 parameter["DataType"] = "String";
3614 parameter["AllowableValues"] = std::move(allowableValues);
3615 nlohmann::json::array_t parameters;
3616 parameters.emplace_back(std::move(parameter));
3617 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3618}
3619
Ed Tanousc1e219d2023-06-07 10:34:33 -07003620inline void handleSystemCollectionResetActionGet(
3621 crow::App& app, const crow::Request& req,
3622 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3623 const std::string& systemName)
3624{
3625 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3626 {
3627 return;
3628 }
3629 if constexpr (bmcwebEnableMultiHost)
3630 {
3631 // Option currently returns no systems. TBD
3632 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3633 systemName);
3634 return;
3635 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003636
Ed Tanousc1e219d2023-06-07 10:34:33 -07003637 if (systemName == "hypervisor")
3638 {
3639 handleHypervisorResetActionGet(asyncResp);
3640 return;
3641 }
3642
3643 if (systemName != "system")
3644 {
3645 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3646 systemName);
3647 return;
3648 }
3649
3650 asyncResp->res.addHeader(
3651 boost::beast::http::field::link,
3652 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3653
3654 asyncResp->res.jsonValue["@odata.id"] =
3655 "/redfish/v1/Systems/system/ResetActionInfo";
3656 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3657 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3658 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3659
Andrew Geissler33e1f122024-02-26 21:10:16 -06003660 // Look to see if system defines AllowedHostTransitions
3661 sdbusplus::asio::getProperty<std::vector<std::string>>(
3662 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3663 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
3664 "AllowedHostTransitions",
3665 [asyncResp](const boost::system::error_code& ec,
3666 const std::vector<std::string>& allowedHostTransitions) {
3667 afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
3668 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003669}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303670/**
3671 * SystemResetActionInfo derived class for delivering Computer Systems
3672 * ResetType AllowableValues using ResetInfo schema.
3673 */
Ed Tanous100afe52023-06-07 13:30:46 -07003674inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303675{
Ed Tanous100afe52023-06-07 13:30:46 -07003676 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3677 .privileges(redfish::privileges::headComputerSystemCollection)
3678 .methods(boost::beast::http::verb::head)(
3679 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3680
3681 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3682 .privileges(redfish::privileges::getComputerSystemCollection)
3683 .methods(boost::beast::http::verb::get)(
3684 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3685
3686 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3687 .privileges(redfish::privileges::headComputerSystem)
3688 .methods(boost::beast::http::verb::head)(
3689 std::bind_front(handleComputerSystemHead, std::ref(app)));
3690
3691 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3692 .privileges(redfish::privileges::getComputerSystem)
3693 .methods(boost::beast::http::verb::get)(
3694 std::bind_front(handleComputerSystemGet, std::ref(app)));
3695
3696 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3697 .privileges(redfish::privileges::patchComputerSystem)
3698 .methods(boost::beast::http::verb::patch)(
3699 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3700
3701 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3702 .privileges(redfish::privileges::postComputerSystem)
3703 .methods(boost::beast::http::verb::post)(std::bind_front(
3704 handleComputerSystemResetActionPost, std::ref(app)));
3705
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003706 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003707 .privileges(redfish::privileges::headActionInfo)
3708 .methods(boost::beast::http::verb::head)(std::bind_front(
3709 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003710 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003711 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003712 .methods(boost::beast::http::verb::get)(std::bind_front(
3713 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003714}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003715} // namespace redfish