blob: 54dbd7030690d10a6231bde622cde3dfa7208f90 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070023#include "generated/enums/computer_system.hpp"
James Feistb49ac872019-05-21 15:12:01 -070024#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060025#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080026#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070027#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080028#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080029#include "registries/privilege_registry.hpp"
30#include "utils/dbus_utils.hpp"
31#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050032#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080033#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070034#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080035
Andrew Geisslerfc903b32023-05-31 14:15:42 -040036#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070037#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080038#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070039#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070040#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040041#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020042#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050043
George Liu7a1dbc42022-12-07 16:03:22 +080044#include <array>
45#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080046#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020047
Ed Tanous1abe55e2018-09-05 08:30:59 -070048namespace redfish
49{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020050
Abhishek Patel5c3e9272021-06-24 10:11:33 -050051const static std::array<std::pair<std::string_view, std::string_view>, 2>
52 protocolToDBusForSystems{
53 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
54
Alpana Kumari9d3ae102019-04-12 06:49:32 -050055/**
56 * @brief Updates the Functional State of DIMMs
57 *
Ed Tanousac106bf2023-06-07 09:24:59 -070058 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050059 * @param[in] dimmState Dimm's Functional state, true/false
60 *
61 * @return None.
62 */
zhanghch058d1b46d2021-04-01 11:18:24 +080063inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070064 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070065 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050066{
Ed Tanous62598e32023-07-17 17:06:25 -070067 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050068
Gunnar Mills4e0453b2020-07-08 14:00:30 -050069 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050070 // Update STATE only if previous State was DISABLED and current Dimm is
71 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070072 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070073 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050074 if (prevMemSummary == "Disabled")
75 {
Ed Tanouse05aec52022-01-25 10:28:56 -080076 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050077 {
Ed Tanousac106bf2023-06-07 09:24:59 -070078 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050079 "Enabled";
80 }
81 }
82}
83
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050084/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085 * @brief Update "ProcessorSummary" "Status" "State" based on
86 * CPU Functional State
87 *
Ed Tanousac106bf2023-06-07 09:24:59 -070088 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089 * @param[in] cpuFunctionalState is CPU functional true/false
90 *
91 * @return None.
92 */
Ed Tanousac106bf2023-06-07 09:24:59 -070093inline void modifyCpuFunctionalState(
94 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050095{
Ed Tanous62598e32023-07-17 17:06:25 -070096 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050097
Ed Tanous02cad962022-06-30 16:50:15 -070098 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -070099 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500100
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500101 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500102 // Update STATE only if previous State was Non_Functional and current CPU is
103 // Functional.
104 if (prevProcState == "Disabled")
105 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800106 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500107 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700108 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500109 "Enabled";
110 }
111 }
112}
113
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500114/*
115 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
116 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700117 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500118 * @param[in] cpuPresenceState CPU present or not
119 *
120 * @return None.
121 */
122inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700123 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500124 bool isCpuPresent)
125{
Ed Tanous62598e32023-07-17 17:06:25 -0700126 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500127
128 if (isCpuPresent)
129 {
130 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700131 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500132 auto* procCountPtr =
133 procCount.get_ptr<nlohmann::json::number_integer_t*>();
134 if (procCountPtr != nullptr)
135 {
136 // shouldn't be possible to be nullptr
137 *procCountPtr += 1;
138 }
139 }
140}
141
Ali Ahmed382d6472021-09-03 16:53:53 -0500142inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700143 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500144 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
145 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500146{
Ed Tanous62598e32023-07-17 17:06:25 -0700147 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500148
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200149 // TODO: Get Model
150
151 const uint16_t* coreCount = nullptr;
152
153 const bool success = sdbusplus::unpackPropertiesNoThrow(
154 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
155
156 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500157 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700158 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200159 return;
160 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500161
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200162 if (coreCount != nullptr)
163 {
164 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700165 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200166 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500167
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200168 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500169 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200170 coreCountJson = *coreCount;
171 }
172 else
173 {
174 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500175 }
176 }
177}
178
179/*
180 * @brief Get ProcessorSummary fields
181 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700182 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500183 * @param[in] service dbus service for Cpu Information
184 * @param[in] path dbus path for Cpu
185 *
186 * @return None.
187 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700188inline void
189 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
190 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500191{
Ed Tanousac106bf2023-06-07 09:24:59 -0700192 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
193 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500194 if (ec3)
195 {
Ed Tanous62598e32023-07-17 17:06:25 -0700196 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500197 return;
198 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700199 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500200 };
201
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500202 // Get the Presence of CPU
203 sdbusplus::asio::getProperty<bool>(
204 *crow::connections::systemBus, service, path,
205 "xyz.openbmc_project.Inventory.Item", "Present",
206 std::move(getCpuPresenceState));
207
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500208 if constexpr (bmcwebEnableProcMemStatus)
209 {
210 auto getCpuFunctionalState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700211 [asyncResp](const boost::system::error_code& ec3,
212 const bool cpuFunctionalCheck) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500213 if (ec3)
214 {
Ed Tanous62598e32023-07-17 17:06:25 -0700215 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500216 return;
217 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700218 modifyCpuFunctionalState(asyncResp, cpuFunctionalCheck);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500219 };
Ali Ahmed382d6472021-09-03 16:53:53 -0500220
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500221 // Get the Functional State
222 sdbusplus::asio::getProperty<bool>(
223 *crow::connections::systemBus, service, path,
224 "xyz.openbmc_project.State.Decorator.OperationalStatus",
225 "Functional", std::move(getCpuFunctionalState));
226 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500227
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200228 sdbusplus::asio::getAllProperties(
229 *crow::connections::systemBus, service, path,
230 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700231 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800232 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800233 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700234 if (ec2)
235 {
Ed Tanous62598e32023-07-17 17:06:25 -0700236 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700237 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700238 return;
239 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700240 getProcessorProperties(asyncResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200241 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500242}
243
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500244/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500245 * @brief processMemoryProperties fields
246 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700247 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500248 * @param[in] service dbus service for memory Information
249 * @param[in] path dbus path for Memory
250 * @param[in] DBUS properties for memory
251 *
252 * @return None.
253 */
254inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700255 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500256 [[maybe_unused]] const std::string& service,
257 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500258 const dbus::utility::DBusPropertiesMap& properties)
259{
Ed Tanous62598e32023-07-17 17:06:25 -0700260 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500261
262 if (properties.empty())
263 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500264 if constexpr (bmcwebEnableProcMemStatus)
265 {
266 sdbusplus::asio::getProperty<bool>(
267 *crow::connections::systemBus, service, path,
268 "xyz.openbmc_project.State."
269 "Decorator.OperationalStatus",
270 "Functional",
Ed Tanousac106bf2023-06-07 09:24:59 -0700271 [asyncResp](const boost::system::error_code& ec3,
272 bool dimmState) {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500273 if (ec3)
274 {
Ed Tanous62598e32023-07-17 17:06:25 -0700275 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500276 return;
277 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700278 updateDimmProperties(asyncResp, dimmState);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500279 });
280 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500281 return;
282 }
283
284 const size_t* memorySizeInKB = nullptr;
285
286 const bool success = sdbusplus::unpackPropertiesNoThrow(
287 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
288 memorySizeInKB);
289
290 if (!success)
291 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700292 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500293 return;
294 }
295
296 if (memorySizeInKB != nullptr)
297 {
298 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700299 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500300 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500301 if (preValue == nullptr)
302 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700303 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500304 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500305 }
306 else
307 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700308 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500309 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
310 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500311 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500312 if constexpr (bmcwebEnableProcMemStatus)
313 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700314 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500315 "Enabled";
316 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500317 }
318}
319
320/*
321 * @brief Get getMemorySummary fields
322 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700323 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500324 * @param[in] service dbus service for memory Information
325 * @param[in] path dbus path for memory
326 *
327 * @return None.
328 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700329inline void
330 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500332{
333 sdbusplus::asio::getAllProperties(
334 *crow::connections::systemBus, service, path,
335 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700336 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500337 path](const boost::system::error_code& ec2,
338 const dbus::utility::DBusPropertiesMap& properties) {
339 if (ec2)
340 {
Ed Tanous62598e32023-07-17 17:06:25 -0700341 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700342 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500343 return;
344 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700345 processMemoryProperties(asyncResp, service, path, properties);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500346 });
347}
348
349/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700350 * @brief Retrieves computer system properties over dbus
351 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700352 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500353 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700354 *
355 * @return None.
356 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700357inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700358 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700359 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700360{
Ed Tanous62598e32023-07-17 17:06:25 -0700361 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800362 constexpr std::array<std::string_view, 5> interfaces = {
363 "xyz.openbmc_project.Inventory.Decorator.Asset",
364 "xyz.openbmc_project.Inventory.Item.Cpu",
365 "xyz.openbmc_project.Inventory.Item.Dimm",
366 "xyz.openbmc_project.Inventory.Item.System",
367 "xyz.openbmc_project.Common.UUID",
368 };
369 dbus::utility::getSubTree(
370 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700371 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800372 systemHealth](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800373 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700374 if (ec)
375 {
Ed Tanous62598e32023-07-17 17:06:25 -0700376 BMCWEB_LOG_DEBUG("DBUS response error");
Ed Tanousac106bf2023-06-07 09:24:59 -0700377 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700378 return;
379 }
380 // Iterate over all retrieved ObjectPaths.
381 for (const std::pair<
382 std::string,
383 std::vector<std::pair<std::string, std::vector<std::string>>>>&
384 object : subtree)
385 {
386 const std::string& path = object.first;
Ed Tanous62598e32023-07-17 17:06:25 -0700387 BMCWEB_LOG_DEBUG("Got path: {}", path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700388 const std::vector<std::pair<std::string, std::vector<std::string>>>&
389 connectionNames = object.second;
390 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700391 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700392 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700393 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700394
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500395 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
396 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
Ed Tanous002d39b2022-05-31 08:59:27 -0700397
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500398 if constexpr (bmcwebEnableProcMemStatus)
Willy Tu13451e32023-05-24 16:08:18 -0700399 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500400 memoryHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700401 asyncResp, "/MemorySummary/Status"_json_pointer);
Willy Tu13451e32023-05-24 16:08:18 -0700402 systemHealth->children.emplace_back(memoryHealth);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500403
404 if constexpr (bmcwebEnableHealthPopulate)
405 {
406 cpuHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700407 asyncResp, "/ProcessorSummary/Status"_json_pointer);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500408
409 systemHealth->children.emplace_back(cpuHealth);
410 }
Willy Tu13451e32023-05-24 16:08:18 -0700411 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700412
413 // This is not system, so check if it's cpu, dimm, UUID or
414 // BiosVer
415 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700416 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700417 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700418 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700419 if (interfaceName ==
420 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700421 {
Ed Tanous62598e32023-07-17 17:06:25 -0700422 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500423
Ed Tanousac106bf2023-06-07 09:24:59 -0700424 getMemorySummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700425
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500426 if constexpr (bmcwebEnableProcMemStatus)
427 {
428 memoryHealth->inventory.emplace_back(path);
429 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700430 }
431 else if (interfaceName ==
432 "xyz.openbmc_project.Inventory.Item.Cpu")
433 {
Ed Tanous62598e32023-07-17 17:06:25 -0700434 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
Ed Tanous002d39b2022-05-31 08:59:27 -0700435
Ed Tanousac106bf2023-06-07 09:24:59 -0700436 getProcessorSummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700437
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500438 if constexpr (bmcwebEnableProcMemStatus)
439 {
440 cpuHealth->inventory.emplace_back(path);
441 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700442 }
443 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
444 {
Ed Tanous62598e32023-07-17 17:06:25 -0700445 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200446
447 sdbusplus::asio::getAllProperties(
448 *crow::connections::systemBus, connection.first,
449 path, "xyz.openbmc_project.Common.UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -0700450 [asyncResp](const boost::system::error_code& ec3,
451 const dbus::utility::DBusPropertiesMap&
452 properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700453 if (ec3)
454 {
Ed Tanous62598e32023-07-17 17:06:25 -0700455 BMCWEB_LOG_DEBUG("DBUS response error {}", ec3);
Ed Tanousac106bf2023-06-07 09:24:59 -0700456 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700457 return;
458 }
Ed Tanous62598e32023-07-17 17:06:25 -0700459 BMCWEB_LOG_DEBUG("Got {} UUID properties.",
460 properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -0700461
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200462 const std::string* uUID = nullptr;
463
464 const bool success =
465 sdbusplus::unpackPropertiesNoThrow(
466 dbus_utils::UnpackErrorPrinter(),
467 properties, "UUID", uUID);
468
469 if (!success)
470 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700471 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200472 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700473 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200474
475 if (uUID != nullptr)
476 {
477 std::string valueStr = *uUID;
478 if (valueStr.size() == 32)
479 {
480 valueStr.insert(8, 1, '-');
481 valueStr.insert(13, 1, '-');
482 valueStr.insert(18, 1, '-');
483 valueStr.insert(23, 1, '-');
484 }
Ed Tanous62598e32023-07-17 17:06:25 -0700485 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
Ed Tanousac106bf2023-06-07 09:24:59 -0700486 asyncResp->res.jsonValue["UUID"] = valueStr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200487 }
488 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700489 }
490 else if (interfaceName ==
491 "xyz.openbmc_project.Inventory.Item.System")
492 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200493 sdbusplus::asio::getAllProperties(
494 *crow::connections::systemBus, connection.first,
495 path,
496 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700497 [asyncResp](const boost::system::error_code& ec2,
498 const dbus::utility::DBusPropertiesMap&
499 propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700500 if (ec2)
501 {
502 // doesn't have to include this
503 // interface
504 return;
505 }
Ed Tanous62598e32023-07-17 17:06:25 -0700506 BMCWEB_LOG_DEBUG("Got {} properties for system",
507 propertiesList.size());
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200508
509 const std::string* partNumber = nullptr;
510 const std::string* serialNumber = nullptr;
511 const std::string* manufacturer = nullptr;
512 const std::string* model = nullptr;
513 const std::string* subModel = nullptr;
514
515 const bool success =
516 sdbusplus::unpackPropertiesNoThrow(
517 dbus_utils::UnpackErrorPrinter(),
518 propertiesList, "PartNumber", partNumber,
519 "SerialNumber", serialNumber,
520 "Manufacturer", manufacturer, "Model",
521 model, "SubModel", subModel);
522
523 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700524 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700525 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200526 return;
527 }
528
529 if (partNumber != nullptr)
530 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700531 asyncResp->res.jsonValue["PartNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200532 *partNumber;
533 }
534
535 if (serialNumber != nullptr)
536 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700537 asyncResp->res.jsonValue["SerialNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200538 *serialNumber;
539 }
540
541 if (manufacturer != nullptr)
542 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700543 asyncResp->res.jsonValue["Manufacturer"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200544 *manufacturer;
545 }
546
547 if (model != nullptr)
548 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700549 asyncResp->res.jsonValue["Model"] = *model;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200550 }
551
552 if (subModel != nullptr)
553 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700554 asyncResp->res.jsonValue["SubModel"] =
555 *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700556 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500557
Ed Tanous002d39b2022-05-31 08:59:27 -0700558 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700559 sw_util::populateSoftwareInformation(
Ed Tanousac106bf2023-06-07 09:24:59 -0700560 asyncResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700561 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200562 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700563
Ed Tanous002d39b2022-05-31 08:59:27 -0700564 sdbusplus::asio::getProperty<std::string>(
565 *crow::connections::systemBus, connection.first,
566 path,
567 "xyz.openbmc_project.Inventory.Decorator."
568 "AssetTag",
569 "AssetTag",
Ed Tanousac106bf2023-06-07 09:24:59 -0700570 [asyncResp](const boost::system::error_code& ec2,
571 const std::string& value) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700572 if (ec2)
573 {
574 // doesn't have to include this
575 // interface
576 return;
577 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700578
Ed Tanousac106bf2023-06-07 09:24:59 -0700579 asyncResp->res.jsonValue["AssetTag"] = value;
Ed Tanous002d39b2022-05-31 08:59:27 -0700580 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700581 }
582 }
583 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700584 }
Ed Tanous66173382018-08-15 18:20:59 -0700585 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700586}
587
588/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700589 * @brief Retrieves host state properties over dbus
590 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700591 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700592 *
593 * @return None.
594 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700595inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700596{
Ed Tanous62598e32023-07-17 17:06:25 -0700597 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700598 sdbusplus::asio::getProperty<std::string>(
599 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
600 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
601 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700602 [asyncResp](const boost::system::error_code& ec,
603 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700604 if (ec)
605 {
606 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700607 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700608 // Service not available, no error, just don't return
609 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700610 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700611 return;
612 }
Ed Tanous62598e32023-07-17 17:06:25 -0700613 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700614 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700615 return;
616 }
Ed Tanous66173382018-08-15 18:20:59 -0700617
Ed Tanous62598e32023-07-17 17:06:25 -0700618 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700619 // Verify Host State
620 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
621 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700622 asyncResp->res.jsonValue["PowerState"] = "On";
623 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700624 }
625 else if (hostState ==
626 "xyz.openbmc_project.State.Host.HostState.Quiesced")
627 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700628 asyncResp->res.jsonValue["PowerState"] = "On";
629 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700630 }
631 else if (hostState ==
632 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
633 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700634 asyncResp->res.jsonValue["PowerState"] = "On";
635 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700636 }
637 else if (
638 hostState ==
639 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
640 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700641 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
642 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700643 }
644 else if (hostState ==
645 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
646 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700647 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
648 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700649 }
650 else
651 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700652 asyncResp->res.jsonValue["PowerState"] = "Off";
653 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700654 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700655 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700656}
657
658/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500659 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530660 *
661 * @param[in] dbusSource The boot source in DBUS speak.
662 *
663 * @return Returns as a string, the boot source in Redfish terms. If translation
664 * cannot be done, returns an empty string.
665 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000666inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530667{
668 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
669 {
670 return "None";
671 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700672 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530673 {
674 return "Hdd";
675 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700676 if (dbusSource ==
677 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530678 {
679 return "Cd";
680 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700681 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682 {
683 return "Pxe";
684 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700685 if (dbusSource ==
686 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700687 {
688 return "Usb";
689 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700690 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530691}
692
693/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300694 * @brief Translates boot type DBUS property value to redfish.
695 *
696 * @param[in] dbusType The boot type in DBUS speak.
697 *
698 * @return Returns as a string, the boot type in Redfish terms. If translation
699 * cannot be done, returns an empty string.
700 */
701inline std::string dbusToRfBootType(const std::string& dbusType)
702{
703 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
704 {
705 return "Legacy";
706 }
707 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
708 {
709 return "UEFI";
710 }
711 return "";
712}
713
714/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500715 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530716 *
717 * @param[in] dbusMode The boot mode in DBUS speak.
718 *
719 * @return Returns as a string, the boot mode in Redfish terms. If translation
720 * cannot be done, returns an empty string.
721 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000722inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530723{
724 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
725 {
726 return "None";
727 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700728 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530729 {
730 return "Diags";
731 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700732 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530733 {
734 return "BiosSetup";
735 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700736 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530737}
738
739/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600740 * @brief Translates boot progress DBUS property value to redfish.
741 *
742 * @param[in] dbusBootProgress The boot progress in DBUS speak.
743 *
744 * @return Returns as a string, the boot progress in Redfish terms. If
745 * translation cannot be done, returns "None".
746 */
747inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
748{
749 // Now convert the D-Bus BootProgress to the appropriate Redfish
750 // enum
751 std::string rfBpLastState = "None";
752 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
753 "ProgressStages.Unspecified")
754 {
755 rfBpLastState = "None";
756 }
757 else if (dbusBootProgress ==
758 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
759 "PrimaryProcInit")
760 {
761 rfBpLastState = "PrimaryProcessorInitializationStarted";
762 }
763 else if (dbusBootProgress ==
764 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
765 "BusInit")
766 {
767 rfBpLastState = "BusInitializationStarted";
768 }
769 else if (dbusBootProgress ==
770 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
771 "MemoryInit")
772 {
773 rfBpLastState = "MemoryInitializationStarted";
774 }
775 else if (dbusBootProgress ==
776 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
777 "SecondaryProcInit")
778 {
779 rfBpLastState = "SecondaryProcessorInitializationStarted";
780 }
781 else if (dbusBootProgress ==
782 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
783 "PCIInit")
784 {
785 rfBpLastState = "PCIResourceConfigStarted";
786 }
787 else if (dbusBootProgress ==
788 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
789 "SystemSetup")
790 {
791 rfBpLastState = "SetupEntered";
792 }
793 else if (dbusBootProgress ==
794 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
795 "SystemInitComplete")
796 {
797 rfBpLastState = "SystemHardwareInitializationComplete";
798 }
799 else if (dbusBootProgress ==
800 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
801 "OSStart")
802 {
803 rfBpLastState = "OSBootStarted";
804 }
805 else if (dbusBootProgress ==
806 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
807 "OSRunning")
808 {
809 rfBpLastState = "OSRunning";
810 }
811 else
812 {
Ed Tanous62598e32023-07-17 17:06:25 -0700813 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600814 // Just return the default
815 }
816 return rfBpLastState;
817}
818
819/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500820 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530821 *
822 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700823 * @param[out] bootSource The DBus source
824 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530825 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700826 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530827 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700828inline int
829 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
830 const std::string& rfSource, std::string& bootSource,
831 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530832{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300833 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
834 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700835
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530836 if (rfSource == "None")
837 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700838 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530839 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700840 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530841 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700842 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
843 }
844 else if (rfSource == "Hdd")
845 {
846 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
847 }
848 else if (rfSource == "Diags")
849 {
850 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
851 }
852 else if (rfSource == "Cd")
853 {
854 bootSource =
855 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
856 }
857 else if (rfSource == "BiosSetup")
858 {
859 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530860 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700861 else if (rfSource == "Usb")
862 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700863 bootSource =
864 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700865 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530866 else
867 {
Ed Tanous62598e32023-07-17 17:06:25 -0700868 BMCWEB_LOG_DEBUG(
869 "Invalid property value for BootSourceOverrideTarget: {}",
870 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700871 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700872 "BootSourceTargetOverride");
873 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530874 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700875 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530876}
Ali Ahmed19817712021-06-29 17:01:52 -0500877
Andrew Geissler978b8802020-11-19 13:36:40 -0600878/**
879 * @brief Retrieves boot progress of the system
880 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700881 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600882 *
883 * @return None.
884 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700885inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600886{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700887 sdbusplus::asio::getProperty<std::string>(
888 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
889 "/xyz/openbmc_project/state/host0",
890 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700891 [asyncResp](const boost::system::error_code& ec,
892 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700893 if (ec)
894 {
895 // BootProgress is an optional object so just do nothing if
896 // not found
897 return;
898 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600899
Ed Tanous62598e32023-07-17 17:06:25 -0700900 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600901
Ed Tanousac106bf2023-06-07 09:24:59 -0700902 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700903 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700904 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600905}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530906
907/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000908 * @brief Retrieves boot progress Last Update of the system
909 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700910 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000911 *
912 * @return None.
913 */
914inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700915 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000916{
917 sdbusplus::asio::getProperty<uint64_t>(
918 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
919 "/xyz/openbmc_project/state/host0",
920 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700921 [asyncResp](const boost::system::error_code& ec,
922 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000923 if (ec)
924 {
Ed Tanous62598e32023-07-17 17:06:25 -0700925 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000926 return;
927 }
928
929 // BootProgressLastUpdate is the last time the BootProgress property
930 // was updated. The time is the Epoch time, number of microseconds
931 // since 1 Jan 1970 00::00::00 UTC."
932 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
933 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
934
935 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700936 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000937 redfish::time_utils::getDateTimeUintUs(lastStateTime);
938 });
939}
940
941/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300942 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300943 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700944 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300945 *
946 * @return None.
947 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300948
Ed Tanousac106bf2023-06-07 09:24:59 -0700949inline void
950 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300951{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700952 sdbusplus::asio::getProperty<std::string>(
953 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
954 "/xyz/openbmc_project/control/host0/boot",
955 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700956 [asyncResp](const boost::system::error_code& ec,
957 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700958 if (ec)
959 {
960 // not an error, don't have to have the interface
961 return;
962 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300963
Ed Tanous62598e32023-07-17 17:06:25 -0700964 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300965
Ed Tanousac106bf2023-06-07 09:24:59 -0700966 asyncResp->res
967 .jsonValue["Boot"]
968 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700969 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300970
Ed Tanous002d39b2022-05-31 08:59:27 -0700971 auto rfType = dbusToRfBootType(bootType);
972 if (rfType.empty())
973 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700974 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700975 return;
976 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300977
Ed Tanousac106bf2023-06-07 09:24:59 -0700978 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700979 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300980}
981
982/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300983 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530984 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700985 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530986 *
987 * @return None.
988 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300989
Ed Tanousac106bf2023-06-07 09:24:59 -0700990inline void
991 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530992{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700993 sdbusplus::asio::getProperty<std::string>(
994 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
995 "/xyz/openbmc_project/control/host0/boot",
996 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700997 [asyncResp](const boost::system::error_code& ec,
998 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700999 if (ec)
1000 {
Ed Tanous62598e32023-07-17 17:06:25 -07001001 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001002 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001003 return;
1004 }
1005
Ed Tanous62598e32023-07-17 17:06:25 -07001006 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -07001007
Ed Tanousac106bf2023-06-07 09:24:59 -07001008 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001009 .jsonValue["Boot"]
1010 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1011 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1012
1013 if (bootModeStr !=
1014 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1015 {
1016 auto rfMode = dbusToRfBootMode(bootModeStr);
1017 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301018 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001019 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001020 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301021 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001022 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001023 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024}
1025
1026/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001027 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301028 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001029 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 *
1031 * @return None.
1032 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001033
1034inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001035 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301036{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001037 sdbusplus::asio::getProperty<std::string>(
1038 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1039 "/xyz/openbmc_project/control/host0/boot",
1040 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001041 [asyncResp](const boost::system::error_code& ec,
1042 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001043 if (ec)
1044 {
Ed Tanous62598e32023-07-17 17:06:25 -07001045 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001046 if (ec.value() == boost::asio::error::host_unreachable)
1047 {
1048 return;
1049 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001050 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001051 return;
1052 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301053
Ed Tanous62598e32023-07-17 17:06:25 -07001054 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301055
Ed Tanous002d39b2022-05-31 08:59:27 -07001056 auto rfSource = dbusToRfBootSource(bootSourceStr);
1057 if (!rfSource.empty())
1058 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001059 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1060 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001061 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001062
Ed Tanous002d39b2022-05-31 08:59:27 -07001063 // Get BootMode as BootSourceOverrideTarget is constructed
1064 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001065 getBootOverrideMode(asyncResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001066 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301067}
1068
1069/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001070 * @brief This functions abstracts all the logic behind getting a
1071 * "BootSourceOverrideEnabled" property from an overall boot override enable
1072 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301073 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001074 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301075 *
1076 * @return None.
1077 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301078
Ed Tanousac106bf2023-06-07 09:24:59 -07001079inline void processBootOverrideEnable(
1080 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1081 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001082{
1083 if (!bootOverrideEnableSetting)
1084 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001085 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1086 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001087 return;
1088 }
1089
1090 // If boot source override is enabled, we need to check 'one_time'
1091 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001092 sdbusplus::asio::getProperty<bool>(
1093 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1094 "/xyz/openbmc_project/control/host0/boot/one_time",
1095 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001096 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001097 if (ec)
1098 {
Ed Tanous62598e32023-07-17 17:06:25 -07001099 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001100 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001101 return;
1102 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301103
Ed Tanous002d39b2022-05-31 08:59:27 -07001104 if (oneTimeSetting)
1105 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001106 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1107 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001108 }
1109 else
1110 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001111 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001112 "Continuous";
1113 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001114 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301115}
1116
1117/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001118 * @brief Retrieves boot override enable over DBUS
1119 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001120 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001121 *
1122 * @return None.
1123 */
1124
1125inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001126 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001127{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001128 sdbusplus::asio::getProperty<bool>(
1129 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1130 "/xyz/openbmc_project/control/host0/boot",
1131 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001132 [asyncResp](const boost::system::error_code& ec,
1133 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001134 if (ec)
1135 {
Ed Tanous62598e32023-07-17 17:06:25 -07001136 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001137 if (ec.value() == boost::asio::error::host_unreachable)
1138 {
1139 return;
1140 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001141 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001142 return;
1143 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001144
Ed Tanousac106bf2023-06-07 09:24:59 -07001145 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001146 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001147}
1148
1149/**
1150 * @brief Retrieves boot source override properties
1151 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001152 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001153 *
1154 * @return None.
1155 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001156inline void
1157 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001158{
Ed Tanous62598e32023-07-17 17:06:25 -07001159 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001160
Ed Tanousac106bf2023-06-07 09:24:59 -07001161 getBootOverrideSource(asyncResp);
1162 getBootOverrideType(asyncResp);
1163 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001164}
1165
1166/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001167 * @brief Retrieves the Last Reset Time
1168 *
1169 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1170 * and power off. Even though this is the "system" Redfish object look at the
1171 * chassis D-Bus interface for the LastStateChangeTime since this has the
1172 * last power operation time.
1173 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001174 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001175 *
1176 * @return None.
1177 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001178inline void
1179 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001180{
Ed Tanous62598e32023-07-17 17:06:25 -07001181 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001182
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001183 sdbusplus::asio::getProperty<uint64_t>(
1184 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1185 "/xyz/openbmc_project/state/chassis0",
1186 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001187 [asyncResp](const boost::system::error_code& ec,
1188 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001189 if (ec)
1190 {
Ed Tanous62598e32023-07-17 17:06:25 -07001191 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001192 return;
1193 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001194
Ed Tanous002d39b2022-05-31 08:59:27 -07001195 // LastStateChangeTime is epoch time, in milliseconds
1196 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1197 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001198
Ed Tanous002d39b2022-05-31 08:59:27 -07001199 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001200 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001201 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001202 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001203}
1204
1205/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001206 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1207 *
1208 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1209 * corresponding property "AttemptsLeft" that keeps track of the amount of
1210 * automatic retry attempts left are hosted in phosphor-state-manager through
1211 * dbus.
1212 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001213 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001214 *
1215 * @return None.
1216 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001217inline void getAutomaticRebootAttempts(
1218 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001219{
Ed Tanous62598e32023-07-17 17:06:25 -07001220 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001221
1222 sdbusplus::asio::getAllProperties(
1223 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1224 "/xyz/openbmc_project/state/host0",
1225 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001226 [asyncResp{asyncResp}](
1227 const boost::system::error_code& ec,
1228 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001229 if (ec)
1230 {
1231 if (ec.value() != EBADR)
1232 {
Ed Tanous62598e32023-07-17 17:06:25 -07001233 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001234 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001235 }
1236 return;
1237 }
1238
1239 const uint32_t* attemptsLeft = nullptr;
1240 const uint32_t* retryAttempts = nullptr;
1241
1242 const bool success = sdbusplus::unpackPropertiesNoThrow(
1243 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1244 attemptsLeft, "RetryAttempts", retryAttempts);
1245
1246 if (!success)
1247 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001248 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001249 return;
1250 }
1251
1252 if (attemptsLeft != nullptr)
1253 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001254 asyncResp->res
1255 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001256 *attemptsLeft;
1257 }
1258
1259 if (retryAttempts != nullptr)
1260 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001261 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001262 *retryAttempts;
1263 }
1264 });
1265}
1266
1267/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001268 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1269 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001270 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001271 *
1272 * @return None.
1273 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001274inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001275 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001276{
Ed Tanous62598e32023-07-17 17:06:25 -07001277 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001278
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001279 sdbusplus::asio::getProperty<bool>(
1280 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1281 "/xyz/openbmc_project/control/host0/auto_reboot",
1282 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001283 [asyncResp](const boost::system::error_code& ec,
1284 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001285 if (ec)
1286 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001287 if (ec.value() != EBADR)
1288 {
Ed Tanous62598e32023-07-17 17:06:25 -07001289 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001290 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001291 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001292 return;
1293 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001294
Ed Tanous62598e32023-07-17 17:06:25 -07001295 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001296 if (autoRebootEnabled)
1297 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001298 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001299 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001300 }
1301 else
1302 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001303 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1304 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001305 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001306 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001307
Ed Tanous002d39b2022-05-31 08:59:27 -07001308 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1309 // and RetryAttempts. OpenBMC only supports Disabled and
1310 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001311 asyncResp->res
1312 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1313 {"Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001314 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001315}
1316
1317/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001318 * @brief Sets RetryAttempts
1319 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001320 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001321 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1322 *
1323 *@return None.
1324 */
1325
Ed Tanousac106bf2023-06-07 09:24:59 -07001326inline void setAutomaticRetryAttempts(
1327 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1328 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001329{
Ed Tanous62598e32023-07-17 17:06:25 -07001330 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001331 sdbusplus::asio::setProperty(
1332 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1333 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001334 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001335 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1336 if (ec)
1337 {
Ed Tanous62598e32023-07-17 17:06:25 -07001338 BMCWEB_LOG_ERROR(
1339 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
George Liu9ae226f2023-06-21 17:56:46 +08001340 messages::internalError(asyncResp->res);
1341 return;
1342 }
1343 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001344}
1345
Ed Tanous8d69c662023-06-21 10:29:06 -07001346inline computer_system::PowerRestorePolicyTypes
1347 redfishPowerRestorePolicyFromDbus(std::string_view value)
1348{
1349 if (value ==
1350 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1351 {
1352 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1353 }
1354 if (value ==
1355 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1356 {
1357 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1358 }
1359 if (value ==
1360 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore")
1361 {
1362 return computer_system::PowerRestorePolicyTypes::LastState;
1363 }
1364 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1365 {
1366 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1367 }
1368 return computer_system::PowerRestorePolicyTypes::Invalid;
1369}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001370/**
George Liuc6a620f2020-04-10 17:18:11 +08001371 * @brief Retrieves power restore policy over DBUS.
1372 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001373 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001374 *
1375 * @return None.
1376 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001377inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001378 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001379{
Ed Tanous62598e32023-07-17 17:06:25 -07001380 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001381
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001382 sdbusplus::asio::getProperty<std::string>(
1383 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1384 "/xyz/openbmc_project/control/host0/power_restore_policy",
1385 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001386 [asyncResp](const boost::system::error_code& ec,
1387 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001388 if (ec)
1389 {
Ed Tanous62598e32023-07-17 17:06:25 -07001390 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001391 return;
1392 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001393 computer_system::PowerRestorePolicyTypes restore =
1394 redfishPowerRestorePolicyFromDbus(policy);
1395 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001396 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001397 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001398 return;
1399 }
George Liuc6a620f2020-04-10 17:18:11 +08001400
Ed Tanous8d69c662023-06-21 10:29:06 -07001401 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001402 });
George Liuc6a620f2020-04-10 17:18:11 +08001403}
1404
1405/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001406 * @brief Stop Boot On Fault over DBUS.
1407 *
1408 * @param[in] asyncResp Shared pointer for generating response message.
1409 *
1410 * @return None.
1411 */
1412inline void
1413 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1414{
Ed Tanous62598e32023-07-17 17:06:25 -07001415 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001416
1417 sdbusplus::asio::getProperty<bool>(
1418 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1419 "/xyz/openbmc_project/logging/settings",
1420 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1421 [asyncResp](const boost::system::error_code& ec, bool value) {
1422 if (ec)
1423 {
1424 if (ec.value() != EBADR)
1425 {
1426 messages::internalError(asyncResp->res);
1427 }
1428 return;
1429 }
1430
1431 if (value)
1432 {
1433 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1434 }
1435 else
1436 {
1437 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1438 }
1439 });
1440}
1441
1442/**
Ali Ahmed19817712021-06-29 17:01:52 -05001443 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1444 * TPM is required for booting the host.
1445 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001446 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001447 *
1448 * @return None.
1449 */
1450inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001451 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001452{
Ed Tanous62598e32023-07-17 17:06:25 -07001453 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001454 constexpr std::array<std::string_view, 1> interfaces = {
1455 "xyz.openbmc_project.Control.TPM.Policy"};
1456 dbus::utility::getSubTree(
1457 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001458 [asyncResp](const boost::system::error_code& ec,
1459 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001460 if (ec)
1461 {
Ed Tanous62598e32023-07-17 17:06:25 -07001462 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1463 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001464 // This is an optional D-Bus object so just return if
1465 // error occurs
1466 return;
1467 }
1468 if (subtree.empty())
1469 {
1470 // As noted above, this is an optional interface so just return
1471 // if there is no instance found
1472 return;
1473 }
1474
1475 /* When there is more than one TPMEnable object... */
1476 if (subtree.size() > 1)
1477 {
Ed Tanous62598e32023-07-17 17:06:25 -07001478 BMCWEB_LOG_DEBUG(
1479 "DBUS response has more than 1 TPM Enable object:{}",
1480 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001481 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001482 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001483 return;
1484 }
1485
1486 // Make sure the Dbus response map has a service and objectPath
1487 // field
1488 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1489 {
Ed Tanous62598e32023-07-17 17:06:25 -07001490 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001491 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001492 return;
1493 }
1494
1495 const std::string& path = subtree[0].first;
1496 const std::string& serv = subtree[0].second.begin()->first;
1497
1498 // Valid TPM Enable object found, now reading the current value
1499 sdbusplus::asio::getProperty<bool>(
1500 *crow::connections::systemBus, serv, path,
1501 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001502 [asyncResp](const boost::system::error_code& ec2,
1503 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001504 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001505 {
Ed Tanous62598e32023-07-17 17:06:25 -07001506 BMCWEB_LOG_DEBUG("D-BUS response error on TPM.Policy Get{}",
1507 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001508 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001509 return;
1510 }
1511
Ed Tanous002d39b2022-05-31 08:59:27 -07001512 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001513 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001514 asyncResp->res
1515 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001516 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001517 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001518 else
1519 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001520 asyncResp->res
1521 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001522 "Disabled";
1523 }
1524 });
George Liue99073f2022-12-09 11:06:16 +08001525 });
Ali Ahmed19817712021-06-29 17:01:52 -05001526}
1527
1528/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001529 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1530 * TPM is required for booting the host.
1531 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001532 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001533 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1534 *
1535 * @return None.
1536 */
1537inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001538 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001539{
Ed Tanous62598e32023-07-17 17:06:25 -07001540 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001541 constexpr std::array<std::string_view, 1> interfaces = {
1542 "xyz.openbmc_project.Control.TPM.Policy"};
1543 dbus::utility::getSubTree(
1544 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001545 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001546 tpmRequired](const boost::system::error_code& ec,
1547 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001548 if (ec)
1549 {
Ed Tanous62598e32023-07-17 17:06:25 -07001550 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1551 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001552 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001553 return;
1554 }
1555 if (subtree.empty())
1556 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001557 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001558 "TrustedModuleRequiredToBoot");
1559 return;
1560 }
1561
1562 /* When there is more than one TPMEnable object... */
1563 if (subtree.size() > 1)
1564 {
Ed Tanous62598e32023-07-17 17:06:25 -07001565 BMCWEB_LOG_DEBUG(
1566 "DBUS response has more than 1 TPM Enable object:{}",
1567 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001568 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001569 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001570 return;
1571 }
1572
1573 // Make sure the Dbus response map has a service and objectPath
1574 // field
1575 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1576 {
Ed Tanous62598e32023-07-17 17:06:25 -07001577 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001578 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001579 return;
1580 }
1581
1582 const std::string& path = subtree[0].first;
1583 const std::string& serv = subtree[0].second.begin()->first;
1584
1585 if (serv.empty())
1586 {
Ed Tanous62598e32023-07-17 17:06:25 -07001587 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001588 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001589 return;
1590 }
1591
1592 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001593 sdbusplus::asio::setProperty(
1594 *crow::connections::systemBus, serv, path,
1595 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001596 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001597 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001598 {
Ed Tanous62598e32023-07-17 17:06:25 -07001599 BMCWEB_LOG_DEBUG(
1600 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1601 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001602 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001603 return;
1604 }
Ed Tanous62598e32023-07-17 17:06:25 -07001605 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liu9ae226f2023-06-21 17:56:46 +08001606 });
George Liue99073f2022-12-09 11:06:16 +08001607 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001608}
1609
1610/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301611 * @brief Sets boot properties into DBUS object(s).
1612 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001613 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001614 * @param[in] bootType The boot type to set.
1615 * @return Integer error code.
1616 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001617inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001618 const std::optional<std::string>& bootType)
1619{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001620 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001621
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001622 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001623 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001624 return;
1625 }
1626
1627 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001628 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001629 // Figure out which DBUS interface and property to use
1630 if (*bootType == "Legacy")
1631 {
1632 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1633 }
1634 else if (*bootType == "UEFI")
1635 {
1636 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1637 }
1638 else
1639 {
Ed Tanous62598e32023-07-17 17:06:25 -07001640 BMCWEB_LOG_DEBUG("Invalid property value for "
1641 "BootSourceOverrideMode: {}",
1642 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001643 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001644 "BootSourceOverrideMode");
1645 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001646 }
1647
1648 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001649 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001650
George Liu9ae226f2023-06-21 17:56:46 +08001651 sdbusplus::asio::setProperty(
1652 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1653 "/xyz/openbmc_project/control/host0/boot",
1654 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001655 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001656 if (ec)
1657 {
Ed Tanous62598e32023-07-17 17:06:25 -07001658 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001659 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001660 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001661 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001662 return;
1663 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001664 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001665 return;
1666 }
Ed Tanous62598e32023-07-17 17:06:25 -07001667 BMCWEB_LOG_DEBUG("Boot type update done.");
George Liu9ae226f2023-06-21 17:56:46 +08001668 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001669}
1670
1671/**
1672 * @brief Sets boot properties into DBUS object(s).
1673 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001674 * @param[in] asyncResp Shared pointer for generating response
1675 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001676 * @param[in] bootType The boot type to set.
1677 * @return Integer error code.
1678 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001679inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001680 const std::optional<std::string>& bootEnable)
1681{
1682 if (!bootEnable)
1683 {
1684 return;
1685 }
1686 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001687 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001688
1689 bool bootOverrideEnable = false;
1690 bool bootOverridePersistent = false;
1691 // Figure out which DBUS interface and property to use
1692 if (*bootEnable == "Disabled")
1693 {
1694 bootOverrideEnable = false;
1695 }
1696 else if (*bootEnable == "Once")
1697 {
1698 bootOverrideEnable = true;
1699 bootOverridePersistent = false;
1700 }
1701 else if (*bootEnable == "Continuous")
1702 {
1703 bootOverrideEnable = true;
1704 bootOverridePersistent = true;
1705 }
1706 else
1707 {
Ed Tanous62598e32023-07-17 17:06:25 -07001708 BMCWEB_LOG_DEBUG(
1709 "Invalid property value for BootSourceOverrideEnabled: {}",
1710 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001711 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001712 "BootSourceOverrideEnabled");
1713 return;
1714 }
1715
1716 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001717 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001718
George Liu9ae226f2023-06-21 17:56:46 +08001719 sdbusplus::asio::setProperty(
1720 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1721 "/xyz/openbmc_project/control/host0/boot",
1722 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001723 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001724 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001725 {
Ed Tanous62598e32023-07-17 17:06:25 -07001726 BMCWEB_LOG_DEBUG("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001727 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001728 return;
1729 }
Ed Tanous62598e32023-07-17 17:06:25 -07001730 BMCWEB_LOG_DEBUG("Boot override enable update done.");
George Liu9ae226f2023-06-21 17:56:46 +08001731 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001732
1733 if (!bootOverrideEnable)
1734 {
1735 return;
1736 }
1737
1738 // In case boot override is enabled we need to set correct value for the
1739 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001740 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1741 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001742
George Liu9ae226f2023-06-21 17:56:46 +08001743 sdbusplus::asio::setProperty(
1744 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1745 "/xyz/openbmc_project/control/host0/boot/one_time",
1746 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001747 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001748 if (ec)
1749 {
Ed Tanous62598e32023-07-17 17:06:25 -07001750 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001751 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001752 return;
1753 }
Ed Tanous62598e32023-07-17 17:06:25 -07001754 BMCWEB_LOG_DEBUG("Boot one_time update done.");
George Liu9ae226f2023-06-21 17:56:46 +08001755 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001756}
1757
1758/**
1759 * @brief Sets boot properties into DBUS object(s).
1760 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001761 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301762 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301763 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001764 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301765 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001766inline void
1767 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1768 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301769{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001770 std::string bootSourceStr;
1771 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001772
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001773 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301774 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001775 return;
1776 }
1777
1778 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001779 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001780 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001781 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1782 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001783 {
Ed Tanous62598e32023-07-17 17:06:25 -07001784 BMCWEB_LOG_DEBUG(
1785 "Invalid property value for BootSourceOverrideTarget: {}",
1786 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001787 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001788 "BootSourceTargetOverride");
1789 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001790 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301791
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001792 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001793 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1794 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001795
George Liu9ae226f2023-06-21 17:56:46 +08001796 sdbusplus::asio::setProperty(
1797 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1798 "/xyz/openbmc_project/control/host0/boot",
1799 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001800 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001801 if (ec)
1802 {
Ed Tanous62598e32023-07-17 17:06:25 -07001803 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001804 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001805 return;
1806 }
Ed Tanous62598e32023-07-17 17:06:25 -07001807 BMCWEB_LOG_DEBUG("Boot source update done.");
George Liu9ae226f2023-06-21 17:56:46 +08001808 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001809
George Liu9ae226f2023-06-21 17:56:46 +08001810 sdbusplus::asio::setProperty(
1811 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1812 "/xyz/openbmc_project/control/host0/boot",
1813 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001814 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001815 if (ec)
1816 {
Ed Tanous62598e32023-07-17 17:06:25 -07001817 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001818 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001819 return;
1820 }
Ed Tanous62598e32023-07-17 17:06:25 -07001821 BMCWEB_LOG_DEBUG("Boot mode update done.");
George Liu9ae226f2023-06-21 17:56:46 +08001822 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001823}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001824
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001825/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001826 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301827 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001828 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301829 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001830 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301831 * @param[in] bootEnable The boot override enable from incoming RF request.
1832 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001833 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301834 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001835
Ed Tanousac106bf2023-06-07 09:24:59 -07001836inline void
1837 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1838 const std::optional<std::string>& bootSource,
1839 const std::optional<std::string>& bootType,
1840 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301841{
Ed Tanous62598e32023-07-17 17:06:25 -07001842 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301843
Ed Tanousac106bf2023-06-07 09:24:59 -07001844 setBootModeOrSource(asyncResp, bootSource);
1845 setBootType(asyncResp, bootType);
1846 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301847}
1848
George Liuc6a620f2020-04-10 17:18:11 +08001849/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001850 * @brief Sets AssetTag
1851 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001852 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001853 * @param[in] assetTag "AssetTag" from request.
1854 *
1855 * @return None.
1856 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001857inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001858 const std::string& assetTag)
1859{
George Liue99073f2022-12-09 11:06:16 +08001860 constexpr std::array<std::string_view, 1> interfaces = {
1861 "xyz.openbmc_project.Inventory.Item.System"};
1862 dbus::utility::getSubTree(
1863 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001864 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001865 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001866 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001867 if (ec)
1868 {
Ed Tanous62598e32023-07-17 17:06:25 -07001869 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001870 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001871 return;
1872 }
1873 if (subtree.empty())
1874 {
Ed Tanous62598e32023-07-17 17:06:25 -07001875 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001876 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001877 return;
1878 }
1879 // Assume only 1 system D-Bus object
1880 // Throw an error if there is more than 1
1881 if (subtree.size() > 1)
1882 {
Ed Tanous62598e32023-07-17 17:06:25 -07001883 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001884 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001885 return;
1886 }
1887 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1888 {
Ed Tanous62598e32023-07-17 17:06:25 -07001889 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001890 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001891 return;
1892 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001893
Ed Tanous002d39b2022-05-31 08:59:27 -07001894 const std::string& path = subtree[0].first;
1895 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001896
Ed Tanous002d39b2022-05-31 08:59:27 -07001897 if (service.empty())
1898 {
Ed Tanous62598e32023-07-17 17:06:25 -07001899 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001900 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001901 return;
1902 }
1903
George Liu9ae226f2023-06-21 17:56:46 +08001904 sdbusplus::asio::setProperty(
1905 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001906 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001907 assetTag, [asyncResp](const boost::system::error_code& ec2) {
1908 if (ec2)
1909 {
Ed Tanous62598e32023-07-17 17:06:25 -07001910 BMCWEB_LOG_DEBUG("D-Bus response error on AssetTag Set {}",
1911 ec2);
George Liu9ae226f2023-06-21 17:56:46 +08001912 messages::internalError(asyncResp->res);
1913 return;
1914 }
1915 });
George Liue99073f2022-12-09 11:06:16 +08001916 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001917}
1918
1919/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001920 * @brief Validate the specified stopBootOnFault is valid and return the
1921 * stopBootOnFault name associated with that string
1922 *
1923 * @param[in] stopBootOnFaultString String representing the desired
1924 * stopBootOnFault
1925 *
1926 * @return stopBootOnFault value or empty if incoming value is not valid
1927 */
1928inline std::optional<bool>
1929 validstopBootOnFault(const std::string& stopBootOnFaultString)
1930{
1931 if (stopBootOnFaultString == "AnyFault")
1932 {
1933 return true;
1934 }
1935
1936 if (stopBootOnFaultString == "Never")
1937 {
1938 return false;
1939 }
1940
1941 return std::nullopt;
1942}
1943
1944/**
1945 * @brief Sets stopBootOnFault
1946 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001947 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001948 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1949 *
1950 * @return None.
1951 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001952inline void
1953 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1954 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001955{
Ed Tanous62598e32023-07-17 17:06:25 -07001956 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001957
1958 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1959 if (!stopBootEnabled)
1960 {
Ed Tanous62598e32023-07-17 17:06:25 -07001961 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1962 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001963 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001964 "StopBootOnFault");
1965 return;
1966 }
1967
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001968 sdbusplus::asio::setProperty(
1969 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1970 "/xyz/openbmc_project/logging/settings",
1971 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1972 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
1973 if (ec)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001974 {
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001975 if (ec.value() != EBADR)
1976 {
1977 messages::internalError(asyncResp->res);
1978 }
1979 return;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001980 }
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001981 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001982}
1983
1984/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001985 * @brief Sets automaticRetry (Auto Reboot)
1986 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001987 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001988 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1989 *
1990 * @return None.
1991 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001992inline void
1993 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1994 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001995{
Ed Tanous62598e32023-07-17 17:06:25 -07001996 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001997
1998 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001999 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002000
2001 if (automaticRetryConfig == "Disabled")
2002 {
2003 autoRebootEnabled = false;
2004 }
2005 else if (automaticRetryConfig == "RetryAttempts")
2006 {
2007 autoRebootEnabled = true;
2008 }
2009 else
2010 {
Ed Tanous62598e32023-07-17 17:06:25 -07002011 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
2012 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07002013 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002014 "AutomaticRetryConfig");
2015 return;
2016 }
2017
George Liu9ae226f2023-06-21 17:56:46 +08002018 sdbusplus::asio::setProperty(
2019 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002020 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002021 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002022 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
2023 if (ec)
2024 {
2025 messages::internalError(asyncResp->res);
2026 return;
2027 }
2028 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002029}
2030
Ed Tanous8d69c662023-06-21 10:29:06 -07002031inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2032{
2033 if (policy == "AlwaysOn")
2034 {
2035 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2036 }
2037 if (policy == "AlwaysOff")
2038 {
2039 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2040 }
2041 if (policy == "LastState")
2042 {
2043 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2044 }
2045 return "";
2046}
2047
Gunnar Mills69f35302020-05-17 16:06:31 -05002048/**
George Liuc6a620f2020-04-10 17:18:11 +08002049 * @brief Sets power restore policy properties.
2050 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002051 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002052 * @param[in] policy power restore policy properties from request.
2053 *
2054 * @return None.
2055 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002056inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002057 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002058 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002059{
Ed Tanous62598e32023-07-17 17:06:25 -07002060 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002061
Ed Tanous8d69c662023-06-21 10:29:06 -07002062 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002063
Ed Tanous8d69c662023-06-21 10:29:06 -07002064 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002065 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002066 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002067 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002068 return;
2069 }
2070
George Liu9ae226f2023-06-21 17:56:46 +08002071 sdbusplus::asio::setProperty(
2072 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002073 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002074 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002075 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2076 if (ec)
2077 {
2078 messages::internalError(asyncResp->res);
2079 return;
2080 }
2081 });
George Liuc6a620f2020-04-10 17:18:11 +08002082}
2083
AppaRao Pulia6349912019-10-18 17:16:08 +05302084#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2085/**
2086 * @brief Retrieves provisioning status
2087 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002088 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302089 *
2090 * @return None.
2091 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002092inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302093{
Ed Tanous62598e32023-07-17 17:06:25 -07002094 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002095 sdbusplus::asio::getAllProperties(
2096 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2097 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002098 [asyncResp](const boost::system::error_code& ec,
2099 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002100 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002101 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2102 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002103 "#OemComputerSystem.OpenBmc";
2104 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002105
Ed Tanous002d39b2022-05-31 08:59:27 -07002106 if (ec)
2107 {
Ed Tanous62598e32023-07-17 17:06:25 -07002108 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002109 // not an error, don't have to have the interface
2110 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2111 return;
2112 }
2113
2114 const bool* provState = nullptr;
2115 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002116
2117 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002118 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2119 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002120
2121 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002122 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002123 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002124 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002125 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302126
Ed Tanous002d39b2022-05-31 08:59:27 -07002127 if ((provState == nullptr) || (lockState == nullptr))
2128 {
Ed Tanous62598e32023-07-17 17:06:25 -07002129 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002130 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002131 return;
2132 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302133
Ed Tanous002d39b2022-05-31 08:59:27 -07002134 if (*provState == true)
2135 {
2136 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302137 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002138 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302139 }
2140 else
2141 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002142 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302143 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002144 }
2145 else
2146 {
2147 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2148 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002149 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302150}
2151#endif
2152
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302153/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002154 * @brief Translate the PowerMode to a response message.
2155 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002156 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002157 * @param[in] modeValue PowerMode value to be translated
2158 *
2159 * @return None.
2160 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002161inline void
2162 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2163 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002164{
George Liu0fda0f12021-11-16 10:06:17 +08002165 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002166 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002167 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002168 }
George Liu0fda0f12021-11-16 10:06:17 +08002169 else if (
2170 modeValue ==
2171 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002172 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002173 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002174 }
George Liu0fda0f12021-11-16 10:06:17 +08002175 else if (modeValue ==
2176 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002177 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002178 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002179 }
George Liu0fda0f12021-11-16 10:06:17 +08002180 else if (modeValue ==
2181 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002182 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002183 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002184 }
2185 else
2186 {
2187 // Any other values would be invalid
Ed Tanous62598e32023-07-17 17:06:25 -07002188 BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue);
Ed Tanousac106bf2023-06-07 09:24:59 -07002189 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002190 }
2191}
2192
2193/**
2194 * @brief Retrieves system power mode
2195 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002196 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002197 *
2198 * @return None.
2199 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002200inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002201{
Ed Tanous62598e32023-07-17 17:06:25 -07002202 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002203
2204 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002205 constexpr std::array<std::string_view, 1> interfaces = {
2206 "xyz.openbmc_project.Control.Power.Mode"};
2207 dbus::utility::getSubTree(
2208 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002209 [asyncResp](const boost::system::error_code& ec,
2210 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002211 if (ec)
2212 {
Ed Tanous62598e32023-07-17 17:06:25 -07002213 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2214 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002215 // This is an optional D-Bus object so just return if
2216 // error occurs
2217 return;
2218 }
2219 if (subtree.empty())
2220 {
2221 // As noted above, this is an optional interface so just return
2222 // if there is no instance found
2223 return;
2224 }
2225 if (subtree.size() > 1)
2226 {
2227 // More then one PowerMode object is not supported and is an
2228 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002229 BMCWEB_LOG_DEBUG(
2230 "Found more than 1 system D-Bus Power.Mode objects: {}",
2231 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002232 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002233 return;
2234 }
2235 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2236 {
Ed Tanous62598e32023-07-17 17:06:25 -07002237 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002238 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002239 return;
2240 }
2241 const std::string& path = subtree[0].first;
2242 const std::string& service = subtree[0].second.begin()->first;
2243 if (service.empty())
2244 {
Ed Tanous62598e32023-07-17 17:06:25 -07002245 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002246 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002247 return;
2248 }
2249 // Valid Power Mode object found, now read the current value
2250 sdbusplus::asio::getProperty<std::string>(
2251 *crow::connections::systemBus, service, path,
2252 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002253 [asyncResp](const boost::system::error_code& ec2,
2254 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002255 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002256 {
Ed Tanous62598e32023-07-17 17:06:25 -07002257 BMCWEB_LOG_DEBUG("DBUS response error on PowerMode Get: {}",
2258 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002259 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002260 return;
2261 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002262
Ed Tanousac106bf2023-06-07 09:24:59 -07002263 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002264 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002265
Ed Tanous62598e32023-07-17 17:06:25 -07002266 BMCWEB_LOG_DEBUG("Current power mode: {}", pmode);
Ed Tanousac106bf2023-06-07 09:24:59 -07002267 translatePowerMode(asyncResp, pmode);
Ed Tanous002d39b2022-05-31 08:59:27 -07002268 });
George Liue99073f2022-12-09 11:06:16 +08002269 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002270}
2271
2272/**
2273 * @brief Validate the specified mode is valid and return the PowerMode
2274 * name associated with that string
2275 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002276 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002277 * @param[in] modeString String representing the desired PowerMode
2278 *
2279 * @return PowerMode value or empty string if mode is not valid
2280 */
2281inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002283 const std::string& modeString)
2284{
2285 std::string mode;
2286
2287 if (modeString == "Static")
2288 {
2289 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2290 }
2291 else if (modeString == "MaximumPerformance")
2292 {
George Liu0fda0f12021-11-16 10:06:17 +08002293 mode =
2294 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002295 }
2296 else if (modeString == "PowerSaving")
2297 {
2298 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2299 }
2300 else
2301 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002302 messages::propertyValueNotInList(asyncResp->res, modeString,
2303 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002304 }
2305 return mode;
2306}
2307
2308/**
2309 * @brief Sets system power mode.
2310 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002311 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002312 * @param[in] pmode System power mode from request.
2313 *
2314 * @return None.
2315 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002316inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002317 const std::string& pmode)
2318{
Ed Tanous62598e32023-07-17 17:06:25 -07002319 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002320
Ed Tanousac106bf2023-06-07 09:24:59 -07002321 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002322 if (powerMode.empty())
2323 {
2324 return;
2325 }
2326
2327 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002328 constexpr std::array<std::string_view, 1> interfaces = {
2329 "xyz.openbmc_project.Control.Power.Mode"};
2330 dbus::utility::getSubTree(
2331 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002332 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002333 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002334 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002335 if (ec)
2336 {
Ed Tanous62598e32023-07-17 17:06:25 -07002337 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2338 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002339 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002340 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002341 return;
2342 }
2343 if (subtree.empty())
2344 {
2345 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002346 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002347 "PowerMode");
2348 return;
2349 }
2350 if (subtree.size() > 1)
2351 {
2352 // More then one PowerMode object is not supported and is an
2353 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002354 BMCWEB_LOG_DEBUG(
2355 "Found more than 1 system D-Bus Power.Mode objects: {}",
2356 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002357 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002358 return;
2359 }
2360 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2361 {
Ed Tanous62598e32023-07-17 17:06:25 -07002362 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002363 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002364 return;
2365 }
2366 const std::string& path = subtree[0].first;
2367 const std::string& service = subtree[0].second.begin()->first;
2368 if (service.empty())
2369 {
Ed Tanous62598e32023-07-17 17:06:25 -07002370 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002371 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002372 return;
2373 }
2374
Ed Tanous62598e32023-07-17 17:06:25 -07002375 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002376
2377 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002378 sdbusplus::asio::setProperty(
2379 *crow::connections::systemBus, service, path,
2380 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002381 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002382 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002383 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002384 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002385 return;
2386 }
George Liu9ae226f2023-06-21 17:56:46 +08002387 });
George Liue99073f2022-12-09 11:06:16 +08002388 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002389}
2390
2391/**
Yong Li51709ff2019-09-30 14:13:04 +08002392 * @brief Translates watchdog timeout action DBUS property value to redfish.
2393 *
2394 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2395 *
2396 * @return Returns as a string, the timeout action in Redfish terms. If
2397 * translation cannot be done, returns an empty string.
2398 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002399inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002400{
2401 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2402 {
2403 return "None";
2404 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002405 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002406 {
2407 return "ResetSystem";
2408 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002409 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002410 {
2411 return "PowerDown";
2412 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002413 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002414 {
2415 return "PowerCycle";
2416 }
2417
2418 return "";
2419}
2420
2421/**
Yong Lic45f0082019-10-10 14:19:01 +08002422 *@brief Translates timeout action from Redfish to DBUS property value.
2423 *
2424 *@param[in] rfAction The timeout action in Redfish.
2425 *
2426 *@return Returns as a string, the time_out action as expected by DBUS.
2427 *If translation cannot be done, returns an empty string.
2428 */
2429
Ed Tanous23a21a12020-07-25 04:45:05 +00002430inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002431{
2432 if (rfAction == "None")
2433 {
2434 return "xyz.openbmc_project.State.Watchdog.Action.None";
2435 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002436 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002437 {
2438 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2439 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002440 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002441 {
2442 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2443 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002444 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002445 {
2446 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2447 }
2448
2449 return "";
2450}
2451
2452/**
Yong Li51709ff2019-09-30 14:13:04 +08002453 * @brief Retrieves host watchdog timer properties over DBUS
2454 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002455 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002456 *
2457 * @return None.
2458 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002459inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002460 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002461{
Ed Tanous62598e32023-07-17 17:06:25 -07002462 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002463 sdbusplus::asio::getAllProperties(
2464 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2465 "/xyz/openbmc_project/watchdog/host0",
2466 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002467 [asyncResp](const boost::system::error_code& ec,
2468 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002469 if (ec)
2470 {
2471 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002472 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002473 return;
2474 }
2475
Ed Tanous62598e32023-07-17 17:06:25 -07002476 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002477
2478 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002479 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002480
2481 // watchdog service is running/enabled
2482 hostWatchdogTimer["Status"]["State"] = "Enabled";
2483
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002484 const bool* enabled = nullptr;
2485 const std::string* expireAction = nullptr;
2486
2487 const bool success = sdbusplus::unpackPropertiesNoThrow(
2488 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2489 "ExpireAction", expireAction);
2490
2491 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002492 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002493 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002494 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002495 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002496
2497 if (enabled != nullptr)
2498 {
2499 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2500 }
2501
2502 if (expireAction != nullptr)
2503 {
2504 std::string action = dbusToRfWatchdogAction(*expireAction);
2505 if (action.empty())
2506 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002507 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002508 return;
2509 }
2510 hostWatchdogTimer["TimeoutAction"] = action;
2511 }
2512 });
Yong Li51709ff2019-09-30 14:13:04 +08002513}
2514
2515/**
Yong Lic45f0082019-10-10 14:19:01 +08002516 * @brief Sets Host WatchDog Timer properties.
2517 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002518 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002519 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2520 * RF request.
2521 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2522 *
2523 * @return None.
2524 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002525inline void
2526 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2527 const std::optional<bool> wdtEnable,
2528 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002529{
Ed Tanous62598e32023-07-17 17:06:25 -07002530 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002531
2532 if (wdtTimeOutAction)
2533 {
2534 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2535 // check if TimeOut Action is Valid
2536 if (wdtTimeOutActStr.empty())
2537 {
Ed Tanous62598e32023-07-17 17:06:25 -07002538 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2539 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002540 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002541 "TimeoutAction");
2542 return;
2543 }
2544
George Liu9ae226f2023-06-21 17:56:46 +08002545 sdbusplus::asio::setProperty(
2546 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002547 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002548 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002549 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2550 if (ec)
2551 {
Ed Tanous62598e32023-07-17 17:06:25 -07002552 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
George Liu9ae226f2023-06-21 17:56:46 +08002553 messages::internalError(asyncResp->res);
2554 return;
2555 }
2556 });
Yong Lic45f0082019-10-10 14:19:01 +08002557 }
2558
2559 if (wdtEnable)
2560 {
George Liu9ae226f2023-06-21 17:56:46 +08002561 sdbusplus::asio::setProperty(
2562 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2563 "/xyz/openbmc_project/watchdog/host0",
2564 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002565 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002566 if (ec)
2567 {
Ed Tanous62598e32023-07-17 17:06:25 -07002568 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002569 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002570 return;
2571 }
George Liu9ae226f2023-06-21 17:56:46 +08002572 });
Yong Lic45f0082019-10-10 14:19:01 +08002573 }
2574}
2575
Chris Cain37bbf982021-09-20 10:53:09 -05002576/**
2577 * @brief Parse the Idle Power Saver properties into json
2578 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002579 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002580 * @param[in] properties IPS property data from DBus.
2581 *
2582 * @return true if successful
2583 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002584inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002585 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002586 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002587{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002588 const bool* enabled = nullptr;
2589 const uint8_t* enterUtilizationPercent = nullptr;
2590 const uint64_t* enterDwellTime = nullptr;
2591 const uint8_t* exitUtilizationPercent = nullptr;
2592 const uint64_t* exitDwellTime = nullptr;
2593
2594 const bool success = sdbusplus::unpackPropertiesNoThrow(
2595 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002596 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2597 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2598 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002599
2600 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002601 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002602 return false;
2603 }
2604
2605 if (enabled != nullptr)
2606 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002607 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002608 }
2609
2610 if (enterUtilizationPercent != nullptr)
2611 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002612 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002613 *enterUtilizationPercent;
2614 }
2615
2616 if (enterDwellTime != nullptr)
2617 {
2618 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002619 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002620 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2621 .count();
2622 }
2623
2624 if (exitUtilizationPercent != nullptr)
2625 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002626 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002627 *exitUtilizationPercent;
2628 }
2629
2630 if (exitDwellTime != nullptr)
2631 {
2632 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002633 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002634 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2635 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002636 }
2637
2638 return true;
2639}
2640
2641/**
2642 * @brief Retrieves host watchdog timer properties over DBUS
2643 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002644 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002645 *
2646 * @return None.
2647 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002648inline void
2649 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002650{
Ed Tanous62598e32023-07-17 17:06:25 -07002651 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002652
2653 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002654 constexpr std::array<std::string_view, 1> interfaces = {
2655 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2656 dbus::utility::getSubTree(
2657 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002658 [asyncResp](const boost::system::error_code& ec,
2659 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002660 if (ec)
2661 {
Ed Tanous62598e32023-07-17 17:06:25 -07002662 BMCWEB_LOG_DEBUG(
2663 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2664 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002665 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002666 return;
2667 }
2668 if (subtree.empty())
2669 {
2670 // This is an optional interface so just return
2671 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002672 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002673 return;
2674 }
2675 if (subtree.size() > 1)
2676 {
2677 // More then one PowerIdlePowerSaver object is not supported and
2678 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002679 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2680 "Power.IdlePowerSaver objects: {}",
2681 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002682 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002683 return;
2684 }
2685 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2686 {
Ed Tanous62598e32023-07-17 17:06:25 -07002687 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002688 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002689 return;
2690 }
2691 const std::string& path = subtree[0].first;
2692 const std::string& service = subtree[0].second.begin()->first;
2693 if (service.empty())
2694 {
Ed Tanous62598e32023-07-17 17:06:25 -07002695 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002696 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002697 return;
2698 }
2699
2700 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002701 sdbusplus::asio::getAllProperties(
2702 *crow::connections::systemBus, service, path,
2703 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002704 [asyncResp](const boost::system::error_code& ec2,
2705 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002706 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002707 {
Ed Tanous62598e32023-07-17 17:06:25 -07002708 BMCWEB_LOG_ERROR(
2709 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002710 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002711 return;
2712 }
2713
Ed Tanousac106bf2023-06-07 09:24:59 -07002714 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002715 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002716 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002717 return;
2718 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002719 });
George Liue99073f2022-12-09 11:06:16 +08002720 });
Chris Cain37bbf982021-09-20 10:53:09 -05002721
Ed Tanous62598e32023-07-17 17:06:25 -07002722 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002723}
2724
2725/**
2726 * @brief Sets Idle Power Saver properties.
2727 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002728 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002729 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2730 * RF request.
2731 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2732 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2733 * before entering idle state.
2734 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2735 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2736 * before exiting idle state
2737 *
2738 * @return None.
2739 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002740inline void
2741 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2742 const std::optional<bool> ipsEnable,
2743 const std::optional<uint8_t> ipsEnterUtil,
2744 const std::optional<uint64_t> ipsEnterTime,
2745 const std::optional<uint8_t> ipsExitUtil,
2746 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002747{
Ed Tanous62598e32023-07-17 17:06:25 -07002748 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002749
2750 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002751 constexpr std::array<std::string_view, 1> interfaces = {
2752 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2753 dbus::utility::getSubTree(
2754 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002755 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002756 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002757 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002758 if (ec)
2759 {
Ed Tanous62598e32023-07-17 17:06:25 -07002760 BMCWEB_LOG_DEBUG(
2761 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2762 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002763 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002764 return;
2765 }
2766 if (subtree.empty())
2767 {
2768 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002769 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002770 "IdlePowerSaver");
2771 return;
2772 }
2773 if (subtree.size() > 1)
2774 {
2775 // More then one PowerIdlePowerSaver object is not supported and
2776 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002777 BMCWEB_LOG_DEBUG(
2778 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2779 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002780 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002781 return;
2782 }
2783 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2784 {
Ed Tanous62598e32023-07-17 17:06:25 -07002785 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002786 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002787 return;
2788 }
2789 const std::string& path = subtree[0].first;
2790 const std::string& service = subtree[0].second.begin()->first;
2791 if (service.empty())
2792 {
Ed Tanous62598e32023-07-17 17:06:25 -07002793 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002794 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002795 return;
2796 }
Chris Cain37bbf982021-09-20 10:53:09 -05002797
Ed Tanous002d39b2022-05-31 08:59:27 -07002798 // Valid Power IdlePowerSaver object found, now set any values that
2799 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002800
Ed Tanous002d39b2022-05-31 08:59:27 -07002801 if (ipsEnable)
2802 {
George Liu9ae226f2023-06-21 17:56:46 +08002803 sdbusplus::asio::setProperty(
2804 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002805 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002806 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
2807 if (ec2)
2808 {
Ed Tanous62598e32023-07-17 17:06:25 -07002809 BMCWEB_LOG_DEBUG("DBUS response error {}", ec2);
George Liu9ae226f2023-06-21 17:56:46 +08002810 messages::internalError(asyncResp->res);
2811 return;
2812 }
2813 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002814 }
2815 if (ipsEnterUtil)
2816 {
George Liu9ae226f2023-06-21 17:56:46 +08002817 sdbusplus::asio::setProperty(
2818 *crow::connections::systemBus, service, path,
2819 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2820 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002821 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002822 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002823 {
Ed Tanous62598e32023-07-17 17:06:25 -07002824 BMCWEB_LOG_DEBUG("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002825 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002826 return;
2827 }
George Liu9ae226f2023-06-21 17:56:46 +08002828 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002829 }
2830 if (ipsEnterTime)
2831 {
2832 // Convert from seconds into milliseconds for DBus
2833 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002834 sdbusplus::asio::setProperty(
2835 *crow::connections::systemBus, service, path,
2836 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2837 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002838 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002839 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002840 {
Ed Tanous62598e32023-07-17 17:06:25 -07002841 BMCWEB_LOG_DEBUG("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002842 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002843 return;
2844 }
George Liu9ae226f2023-06-21 17:56:46 +08002845 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002846 }
2847 if (ipsExitUtil)
2848 {
George Liu9ae226f2023-06-21 17:56:46 +08002849 sdbusplus::asio::setProperty(
2850 *crow::connections::systemBus, service, path,
2851 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2852 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002853 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002854 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002855 {
Ed Tanous62598e32023-07-17 17:06:25 -07002856 BMCWEB_LOG_DEBUG("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002857 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002858 return;
2859 }
George Liu9ae226f2023-06-21 17:56:46 +08002860 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002861 }
2862 if (ipsExitTime)
2863 {
2864 // Convert from seconds into milliseconds for DBus
2865 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002866 sdbusplus::asio::setProperty(
2867 *crow::connections::systemBus, service, path,
2868 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2869 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002870 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002871 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002872 {
Ed Tanous62598e32023-07-17 17:06:25 -07002873 BMCWEB_LOG_DEBUG("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002874 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002875 return;
2876 }
George Liu9ae226f2023-06-21 17:56:46 +08002877 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002878 }
George Liue99073f2022-12-09 11:06:16 +08002879 });
Chris Cain37bbf982021-09-20 10:53:09 -05002880
Ed Tanous62598e32023-07-17 17:06:25 -07002881 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002882}
2883
Ed Tanousc1e219d2023-06-07 10:34:33 -07002884inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002885 crow::App& app, const crow::Request& req,
2886 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2887{
2888 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2889 {
2890 return;
2891 }
2892 asyncResp->res.addHeader(
2893 boost::beast::http::field::link,
2894 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2895}
2896
Ed Tanousc1e219d2023-06-07 10:34:33 -07002897inline void handleComputerSystemCollectionGet(
2898 crow::App& app, const crow::Request& req,
2899 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2900{
2901 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2902 {
2903 return;
2904 }
2905
2906 asyncResp->res.addHeader(
2907 boost::beast::http::field::link,
2908 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2909 asyncResp->res.jsonValue["@odata.type"] =
2910 "#ComputerSystemCollection.ComputerSystemCollection";
2911 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2912 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2913
2914 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2915 ifaceArray = nlohmann::json::array();
2916 if constexpr (bmcwebEnableMultiHost)
2917 {
2918 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2919 // Option currently returns no systems. TBD
2920 return;
2921 }
2922 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2923 nlohmann::json::object_t system;
2924 system["@odata.id"] = "/redfish/v1/Systems/system";
2925 ifaceArray.emplace_back(std::move(system));
2926 sdbusplus::asio::getProperty<std::string>(
2927 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2928 "/xyz/openbmc_project/network/hypervisor",
2929 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2930 [asyncResp](const boost::system::error_code& ec2,
2931 const std::string& /*hostName*/) {
2932 if (ec2)
2933 {
2934 return;
2935 }
2936 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2937 if (val == asyncResp->res.jsonValue.end())
2938 {
Ed Tanous62598e32023-07-17 17:06:25 -07002939 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002940 return;
2941 }
2942 uint64_t* count = val->get_ptr<uint64_t*>();
2943 if (count == nullptr)
2944 {
Ed Tanous62598e32023-07-17 17:06:25 -07002945 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002946 return;
2947 }
2948 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07002949 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002950 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2951 nlohmann::json::object_t hypervisor;
2952 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2953 ifaceArray2.emplace_back(std::move(hypervisor));
2954 });
2955}
2956
Yong Lic45f0082019-10-10 14:19:01 +08002957/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002958 * Function transceives data with dbus directly.
2959 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002960inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002961{
Patrick Williams89492a12023-05-10 07:51:34 -05002962 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2963 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2964 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002965 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002966 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002967
2968 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002969 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002970 if (ec)
2971 {
Ed Tanous62598e32023-07-17 17:06:25 -07002972 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002973 messages::internalError(asyncResp->res);
2974 return;
2975 }
2976 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002977 },
2978 serviceName, objectPath, interfaceName, method);
2979}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002980
2981/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002982 * Handle error responses from d-bus for system power requests
2983 */
2984inline void handleSystemActionResetError(const boost::system::error_code& ec,
2985 const sdbusplus::message_t& eMsg,
2986 std::string_view resetType,
2987 crow::Response& res)
2988{
2989 if (ec.value() == boost::asio::error::invalid_argument)
2990 {
2991 messages::actionParameterNotSupported(res, resetType, "Reset");
2992 return;
2993 }
2994
2995 if (eMsg.get_error() == nullptr)
2996 {
Ed Tanous62598e32023-07-17 17:06:25 -07002997 BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002998 messages::internalError(res);
2999 return;
3000 }
3001 std::string_view errorMessage = eMsg.get_error()->name;
3002
3003 // If operation failed due to BMC not being in Ready state, tell
3004 // user to retry in a bit
3005 if ((errorMessage ==
3006 std::string_view(
3007 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3008 (errorMessage ==
3009 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3010 {
Ed Tanous62598e32023-07-17 17:06:25 -07003011 BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003012 messages::serviceTemporarilyUnavailable(res, "10");
3013 return;
3014 }
3015
Ed Tanous62598e32023-07-17 17:06:25 -07003016 BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
3017 errorMessage);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003018 messages::internalError(res);
3019}
3020
Ed Tanousc1e219d2023-06-07 10:34:33 -07003021inline void handleComputerSystemResetActionPost(
3022 crow::App& app, const crow::Request& req,
3023 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3024 const std::string& systemName)
3025{
3026 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3027 {
3028 return;
3029 }
3030 if (systemName != "system")
3031 {
3032 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3033 systemName);
3034 return;
3035 }
3036 if constexpr (bmcwebEnableMultiHost)
3037 {
3038 // Option currently returns no systems. TBD
3039 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3040 systemName);
3041 return;
3042 }
3043 std::string resetType;
3044 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3045 {
3046 return;
3047 }
3048
3049 // Get the command and host vs. chassis
3050 std::string command;
3051 bool hostCommand = true;
3052 if ((resetType == "On") || (resetType == "ForceOn"))
3053 {
3054 command = "xyz.openbmc_project.State.Host.Transition.On";
3055 hostCommand = true;
3056 }
3057 else if (resetType == "ForceOff")
3058 {
3059 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3060 hostCommand = false;
3061 }
3062 else if (resetType == "ForceRestart")
3063 {
3064 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3065 hostCommand = true;
3066 }
3067 else if (resetType == "GracefulShutdown")
3068 {
3069 command = "xyz.openbmc_project.State.Host.Transition.Off";
3070 hostCommand = true;
3071 }
3072 else if (resetType == "GracefulRestart")
3073 {
3074 command =
3075 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3076 hostCommand = true;
3077 }
3078 else if (resetType == "PowerCycle")
3079 {
3080 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3081 hostCommand = true;
3082 }
3083 else if (resetType == "Nmi")
3084 {
3085 doNMI(asyncResp);
3086 return;
3087 }
3088 else
3089 {
3090 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3091 return;
3092 }
3093
3094 if (hostCommand)
3095 {
George Liu9ae226f2023-06-21 17:56:46 +08003096 sdbusplus::asio::setProperty(
3097 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3098 "/xyz/openbmc_project/state/host0",
3099 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3100 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003101 [asyncResp, resetType](const boost::system::error_code& ec,
3102 sdbusplus::message_t& sdbusErrMsg) {
3103 if (ec)
3104 {
3105 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3106 asyncResp->res);
3107
3108 return;
3109 }
3110 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003111 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003112 }
3113 else
3114 {
George Liu9ae226f2023-06-21 17:56:46 +08003115 sdbusplus::asio::setProperty(
3116 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3117 "/xyz/openbmc_project/state/chassis0",
3118 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3119 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003120 [asyncResp, resetType](const boost::system::error_code& ec,
3121 sdbusplus::message_t& sdbusErrMsg) {
3122 if (ec)
3123 {
3124 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3125 asyncResp->res);
3126 return;
3127 }
3128 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003129 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003130 }
3131}
3132
Ed Tanousc1e219d2023-06-07 10:34:33 -07003133inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003134 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003135 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3136 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003137{
3138 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3139 {
3140 return;
3141 }
3142
3143 asyncResp->res.addHeader(
3144 boost::beast::http::field::link,
3145 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3146}
3147
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003148inline void afterPortRequest(
3149 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3150 const boost::system::error_code& ec,
3151 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3152{
3153 if (ec)
3154 {
3155 messages::internalError(asyncResp->res);
3156 return;
3157 }
3158 for (const auto& data : socketData)
3159 {
3160 const std::string& socketPath = get<0>(data);
3161 const std::string& protocolName = get<1>(data);
3162 bool isProtocolEnabled = get<2>(data);
3163 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3164 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3165 // need to retrieve port number for
3166 // obmc-console-ssh service
3167 if (protocolName == "SSH")
3168 {
3169 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003170 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003171 int portNumber) {
3172 if (ec1)
3173 {
3174 messages::internalError(asyncResp->res);
3175 return;
3176 }
3177 nlohmann::json& dataJson1 =
3178 asyncResp->res.jsonValue["SerialConsole"];
3179 dataJson1[protocolName]["Port"] = portNumber;
3180 });
3181 }
3182 }
3183}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003184
3185inline void
3186 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3187 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3188 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003189{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003190 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3191 {
3192 return;
3193 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003194
Ed Tanousc1e219d2023-06-07 10:34:33 -07003195 if constexpr (bmcwebEnableMultiHost)
3196 {
3197 // Option currently returns no systems. TBD
3198 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3199 systemName);
3200 return;
3201 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003202
Ed Tanousc1e219d2023-06-07 10:34:33 -07003203 if (systemName == "hypervisor")
3204 {
3205 handleHypervisorSystemGet(asyncResp);
3206 return;
3207 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003208
Ed Tanousc1e219d2023-06-07 10:34:33 -07003209 if (systemName != "system")
3210 {
3211 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3212 systemName);
3213 return;
3214 }
3215 asyncResp->res.addHeader(
3216 boost::beast::http::field::link,
3217 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3218 asyncResp->res.jsonValue["@odata.type"] =
3219 "#ComputerSystem.v1_16_0.ComputerSystem";
3220 asyncResp->res.jsonValue["Name"] = "system";
3221 asyncResp->res.jsonValue["Id"] = "system";
3222 asyncResp->res.jsonValue["SystemType"] = "Physical";
3223 asyncResp->res.jsonValue["Description"] = "Computer System";
3224 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3225 if constexpr (bmcwebEnableProcMemStatus)
3226 {
3227 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3228 "Disabled";
3229 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3230 "Disabled";
3231 }
3232 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003233 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003234 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003235
Ed Tanousc1e219d2023-06-07 10:34:33 -07003236 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3237 "/redfish/v1/Systems/system/Processors";
3238 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3239 "/redfish/v1/Systems/system/Memory";
3240 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3241 "/redfish/v1/Systems/system/Storage";
3242 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3243 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003244
Ed Tanousc1e219d2023-06-07 10:34:33 -07003245 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3246 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3247 asyncResp->res
3248 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3249 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003250
Ed Tanousc1e219d2023-06-07 10:34:33 -07003251 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3252 "/redfish/v1/Systems/system/LogServices";
3253 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3254 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003255
Ed Tanousc1e219d2023-06-07 10:34:33 -07003256 nlohmann::json::array_t managedBy;
3257 nlohmann::json& manager = managedBy.emplace_back();
3258 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3259 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3260 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3261 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003262
Ed Tanousc1e219d2023-06-07 10:34:33 -07003263 // Fill in SerialConsole info
3264 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3265 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003266
Ed Tanousc1e219d2023-06-07 10:34:33 -07003267 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3268 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3269 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3270 "Press ~. to exit console";
3271 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3272 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003273
3274#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003275 // Fill in GraphicalConsole info
3276 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3277 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3278 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3279 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003280
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003281#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003282
Ed Tanousc1e219d2023-06-07 10:34:33 -07003283 auto health = std::make_shared<HealthPopulate>(asyncResp);
3284 if constexpr (bmcwebEnableHealthPopulate)
3285 {
3286 constexpr std::array<std::string_view, 4> inventoryForSystems{
3287 "xyz.openbmc_project.Inventory.Item.Dimm",
3288 "xyz.openbmc_project.Inventory.Item.Cpu",
3289 "xyz.openbmc_project.Inventory.Item.Drive",
3290 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003291
Ed Tanousc1e219d2023-06-07 10:34:33 -07003292 dbus::utility::getSubTreePaths(
3293 "/", 0, inventoryForSystems,
3294 [health](const boost::system::error_code& ec,
3295 const std::vector<std::string>& resp) {
3296 if (ec)
3297 {
3298 // no inventory
3299 return;
3300 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003301
Ed Tanousc1e219d2023-06-07 10:34:33 -07003302 health->inventory = resp;
3303 });
3304 health->populate();
3305 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003306
Ed Tanousc1e219d2023-06-07 10:34:33 -07003307 getMainChassisId(asyncResp,
3308 [](const std::string& chassisId,
3309 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3310 nlohmann::json::array_t chassisArray;
3311 nlohmann::json& chassis = chassisArray.emplace_back();
3312 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3313 chassisId);
3314 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3315 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003316
Ed Tanousc1e219d2023-06-07 10:34:33 -07003317 getLocationIndicatorActive(asyncResp);
3318 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3319 getIndicatorLedState(asyncResp);
3320 getComputerSystem(asyncResp, health);
3321 getHostState(asyncResp);
3322 getBootProperties(asyncResp);
3323 getBootProgress(asyncResp);
3324 getBootProgressLastStateTime(asyncResp);
3325 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3326 getHostWatchdogTimer(asyncResp);
3327 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003328 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003329 getAutomaticRetryPolicy(asyncResp);
3330 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003331#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003332 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003333#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003334 getTrustedModuleRequiredToBoot(asyncResp);
3335 getPowerMode(asyncResp);
3336 getIdlePowerSaver(asyncResp);
3337}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003338
Ed Tanousc1e219d2023-06-07 10:34:33 -07003339inline void handleComputerSystemPatch(
3340 crow::App& app, const crow::Request& req,
3341 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3342 const std::string& systemName)
3343{
3344 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3345 {
3346 return;
3347 }
3348 if constexpr (bmcwebEnableMultiHost)
3349 {
3350 // Option currently returns no systems. TBD
3351 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3352 systemName);
3353 return;
3354 }
3355 if (systemName != "system")
3356 {
3357 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3358 systemName);
3359 return;
3360 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003361
Ed Tanousc1e219d2023-06-07 10:34:33 -07003362 asyncResp->res.addHeader(
3363 boost::beast::http::field::link,
3364 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003365
Ed Tanousc1e219d2023-06-07 10:34:33 -07003366 std::optional<bool> locationIndicatorActive;
3367 std::optional<std::string> indicatorLed;
3368 std::optional<std::string> assetTag;
3369 std::optional<std::string> powerRestorePolicy;
3370 std::optional<std::string> powerMode;
3371 std::optional<bool> wdtEnable;
3372 std::optional<std::string> wdtTimeOutAction;
3373 std::optional<std::string> bootSource;
3374 std::optional<std::string> bootType;
3375 std::optional<std::string> bootEnable;
3376 std::optional<std::string> bootAutomaticRetry;
3377 std::optional<uint32_t> bootAutomaticRetryAttempts;
3378 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003379 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003380 std::optional<bool> ipsEnable;
3381 std::optional<uint8_t> ipsEnterUtil;
3382 std::optional<uint64_t> ipsEnterTime;
3383 std::optional<uint8_t> ipsExitUtil;
3384 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003385
Ed Tanousc1e219d2023-06-07 10:34:33 -07003386 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003387 if (!json_util::readJsonPatch(
3388 req, asyncResp->res,
3389 "IndicatorLED", indicatorLed,
3390 "LocationIndicatorActive", locationIndicatorActive,
3391 "AssetTag", assetTag,
3392 "PowerRestorePolicy", powerRestorePolicy,
3393 "PowerMode", powerMode,
3394 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3395 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3396 "Boot/BootSourceOverrideTarget", bootSource,
3397 "Boot/BootSourceOverrideMode", bootType,
3398 "Boot/BootSourceOverrideEnabled", bootEnable,
3399 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003400 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003401 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003402 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003403 "IdlePowerSaver/Enabled", ipsEnable,
3404 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3405 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3406 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3407 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3408 {
3409 return;
3410 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003411 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003412
Ed Tanousc1e219d2023-06-07 10:34:33 -07003413 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003414
Ed Tanousc1e219d2023-06-07 10:34:33 -07003415 if (assetTag)
3416 {
3417 setAssetTag(asyncResp, *assetTag);
3418 }
James Feistb49ac872019-05-21 15:12:01 -07003419
Ed Tanousc1e219d2023-06-07 10:34:33 -07003420 if (wdtEnable || wdtTimeOutAction)
3421 {
3422 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3423 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003424
Ed Tanousc1e219d2023-06-07 10:34:33 -07003425 if (bootSource || bootType || bootEnable)
3426 {
3427 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3428 }
3429 if (bootAutomaticRetry)
3430 {
3431 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3432 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003433
Ed Tanousc1e219d2023-06-07 10:34:33 -07003434 if (bootAutomaticRetryAttempts)
3435 {
3436 setAutomaticRetryAttempts(asyncResp,
3437 bootAutomaticRetryAttempts.value());
3438 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003439
Ed Tanousc1e219d2023-06-07 10:34:33 -07003440 if (bootTrustedModuleRequired)
3441 {
3442 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3443 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003444
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003445 if (stopBootOnFault)
3446 {
3447 setStopBootOnFault(asyncResp, *stopBootOnFault);
3448 }
3449
Ed Tanousc1e219d2023-06-07 10:34:33 -07003450 if (locationIndicatorActive)
3451 {
3452 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3453 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003454
Ed Tanousc1e219d2023-06-07 10:34:33 -07003455 // TODO (Gunnar): Remove IndicatorLED after enough time has
3456 // passed
3457 if (indicatorLed)
3458 {
3459 setIndicatorLedState(asyncResp, *indicatorLed);
3460 asyncResp->res.addHeader(boost::beast::http::field::warning,
3461 "299 - \"IndicatorLED is deprecated. Use "
3462 "LocationIndicatorActive instead.\"");
3463 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003464
Ed Tanousc1e219d2023-06-07 10:34:33 -07003465 if (powerRestorePolicy)
3466 {
3467 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3468 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003469
Ed Tanousc1e219d2023-06-07 10:34:33 -07003470 if (powerMode)
3471 {
3472 setPowerMode(asyncResp, *powerMode);
3473 }
Chris Cain37bbf982021-09-20 10:53:09 -05003474
Ed Tanousc1e219d2023-06-07 10:34:33 -07003475 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3476 {
3477 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3478 ipsExitUtil, ipsExitTime);
3479 }
3480}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303481
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003482inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003483 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003484 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003485 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003486{
3487 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3488 {
3489 return;
3490 }
3491 asyncResp->res.addHeader(
3492 boost::beast::http::field::link,
3493 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3494}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003495inline void handleSystemCollectionResetActionGet(
3496 crow::App& app, const crow::Request& req,
3497 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3498 const std::string& systemName)
3499{
3500 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3501 {
3502 return;
3503 }
3504 if constexpr (bmcwebEnableMultiHost)
3505 {
3506 // Option currently returns no systems. TBD
3507 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3508 systemName);
3509 return;
3510 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003511
Ed Tanousc1e219d2023-06-07 10:34:33 -07003512 if (systemName == "hypervisor")
3513 {
3514 handleHypervisorResetActionGet(asyncResp);
3515 return;
3516 }
3517
3518 if (systemName != "system")
3519 {
3520 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3521 systemName);
3522 return;
3523 }
3524
3525 asyncResp->res.addHeader(
3526 boost::beast::http::field::link,
3527 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3528
3529 asyncResp->res.jsonValue["@odata.id"] =
3530 "/redfish/v1/Systems/system/ResetActionInfo";
3531 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3532 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3533 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3534
3535 nlohmann::json::array_t parameters;
3536 nlohmann::json::object_t parameter;
3537
3538 parameter["Name"] = "ResetType";
3539 parameter["Required"] = true;
3540 parameter["DataType"] = "String";
3541 nlohmann::json::array_t allowableValues;
3542 allowableValues.emplace_back("On");
3543 allowableValues.emplace_back("ForceOff");
3544 allowableValues.emplace_back("ForceOn");
3545 allowableValues.emplace_back("ForceRestart");
3546 allowableValues.emplace_back("GracefulRestart");
3547 allowableValues.emplace_back("GracefulShutdown");
3548 allowableValues.emplace_back("PowerCycle");
3549 allowableValues.emplace_back("Nmi");
3550 parameter["AllowableValues"] = std::move(allowableValues);
3551 parameters.emplace_back(std::move(parameter));
3552
3553 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3554}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303555/**
3556 * SystemResetActionInfo derived class for delivering Computer Systems
3557 * ResetType AllowableValues using ResetInfo schema.
3558 */
Ed Tanous100afe52023-06-07 13:30:46 -07003559inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303560{
Ed Tanous100afe52023-06-07 13:30:46 -07003561 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3562 .privileges(redfish::privileges::headComputerSystemCollection)
3563 .methods(boost::beast::http::verb::head)(
3564 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3565
3566 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3567 .privileges(redfish::privileges::getComputerSystemCollection)
3568 .methods(boost::beast::http::verb::get)(
3569 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3570
3571 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3572 .privileges(redfish::privileges::headComputerSystem)
3573 .methods(boost::beast::http::verb::head)(
3574 std::bind_front(handleComputerSystemHead, std::ref(app)));
3575
3576 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3577 .privileges(redfish::privileges::getComputerSystem)
3578 .methods(boost::beast::http::verb::get)(
3579 std::bind_front(handleComputerSystemGet, std::ref(app)));
3580
3581 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3582 .privileges(redfish::privileges::patchComputerSystem)
3583 .methods(boost::beast::http::verb::patch)(
3584 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3585
3586 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3587 .privileges(redfish::privileges::postComputerSystem)
3588 .methods(boost::beast::http::verb::post)(std::bind_front(
3589 handleComputerSystemResetActionPost, std::ref(app)));
3590
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003591 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003592 .privileges(redfish::privileges::headActionInfo)
3593 .methods(boost::beast::http::verb::head)(std::bind_front(
3594 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003595 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003596 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003597 .methods(boost::beast::http::verb::get)(std::bind_front(
3598 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003599}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003600} // namespace redfish