blob: d8cf644cb515fc879d5f21d9a2414e1d43d0d55b [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);
Patrick Williams5a39f772023-10-20 11:20:21 -0500241 });
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);
Patrick Williams5a39f772023-10-20 11:20:21 -0500279 });
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500280 }
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);
Patrick Williams5a39f772023-10-20 11:20:21 -0500346 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500347}
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 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -0500376 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
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 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -0500455 BMCWEB_LOG_ERROR("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 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500488 });
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);
Patrick Williams5a39f772023-10-20 11:20:21 -0500562 });
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;
Patrick Williams5a39f772023-10-20 11:20:21 -0500580 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700581 }
582 }
583 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700584 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500585 });
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 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500655 });
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);
Patrick Williams5a39f772023-10-20 11:20:21 -0500904 });
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);
Patrick Williams5a39f772023-10-20 11:20:21 -0500938 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000939}
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;
Patrick Williams5a39f772023-10-20 11:20:21 -0500979 });
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 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001001 BMCWEB_LOG_ERROR("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 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001023 });
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 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001045 if (ec.value() == boost::asio::error::host_unreachable)
1046 {
1047 return;
1048 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001049 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
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);
Patrick Williams5a39f772023-10-20 11:20:21 -05001066 });
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 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001099 BMCWEB_LOG_ERROR("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 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001114 });
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 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001136 if (ec.value() == boost::asio::error::host_unreachable)
1137 {
1138 return;
1139 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001140 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
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);
Patrick Williams5a39f772023-10-20 11:20:21 -05001146 });
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);
Patrick Williams5a39f772023-10-20 11:20:21 -05001202 });
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 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001264 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001265}
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"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001314 });
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) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001336 if (ec)
1337 {
1338 BMCWEB_LOG_ERROR(
1339 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1340 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 ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001360 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001361 {
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;
Patrick Williams5a39f772023-10-20 11:20:21 -05001402 });
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 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001426 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001427 messages::internalError(asyncResp->res);
1428 }
1429 return;
1430 }
1431
1432 if (value)
1433 {
1434 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1435 }
1436 else
1437 {
1438 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1439 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001440 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001441}
1442
1443/**
Ali Ahmed19817712021-06-29 17:01:52 -05001444 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1445 * TPM is required for booting the host.
1446 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001447 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001448 *
1449 * @return None.
1450 */
1451inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001452 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001453{
Ed Tanous62598e32023-07-17 17:06:25 -07001454 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001455 constexpr std::array<std::string_view, 1> interfaces = {
1456 "xyz.openbmc_project.Control.TPM.Policy"};
1457 dbus::utility::getSubTree(
1458 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001459 [asyncResp](const boost::system::error_code& ec,
1460 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001461 if (ec)
1462 {
Ed Tanous62598e32023-07-17 17:06:25 -07001463 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1464 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001465 // This is an optional D-Bus object so just return if
1466 // error occurs
1467 return;
1468 }
1469 if (subtree.empty())
1470 {
1471 // As noted above, this is an optional interface so just return
1472 // if there is no instance found
1473 return;
1474 }
1475
1476 /* When there is more than one TPMEnable object... */
1477 if (subtree.size() > 1)
1478 {
Ed Tanous62598e32023-07-17 17:06:25 -07001479 BMCWEB_LOG_DEBUG(
1480 "DBUS response has more than 1 TPM Enable object:{}",
1481 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001482 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001483 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001484 return;
1485 }
1486
1487 // Make sure the Dbus response map has a service and objectPath
1488 // field
1489 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1490 {
Ed Tanous62598e32023-07-17 17:06:25 -07001491 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001492 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001493 return;
1494 }
1495
1496 const std::string& path = subtree[0].first;
1497 const std::string& serv = subtree[0].second.begin()->first;
1498
1499 // Valid TPM Enable object found, now reading the current value
1500 sdbusplus::asio::getProperty<bool>(
1501 *crow::connections::systemBus, serv, path,
1502 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001503 [asyncResp](const boost::system::error_code& ec2,
1504 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001505 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001506 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001507 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001508 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001509 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001510 return;
1511 }
1512
Ed Tanous002d39b2022-05-31 08:59:27 -07001513 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001514 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001515 asyncResp->res
1516 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001517 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001518 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001519 else
1520 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001521 asyncResp->res
1522 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001523 "Disabled";
1524 }
George Liue99073f2022-12-09 11:06:16 +08001525 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001526 });
Ali Ahmed19817712021-06-29 17:01:52 -05001527}
1528
1529/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001530 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1531 * TPM is required for booting the host.
1532 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001533 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001534 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1535 *
1536 * @return None.
1537 */
1538inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001539 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001540{
Ed Tanous62598e32023-07-17 17:06:25 -07001541 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001542 constexpr std::array<std::string_view, 1> interfaces = {
1543 "xyz.openbmc_project.Control.TPM.Policy"};
1544 dbus::utility::getSubTree(
1545 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001546 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001547 tpmRequired](const boost::system::error_code& ec,
1548 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001549 if (ec)
1550 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001551 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001552 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001553 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001554 return;
1555 }
1556 if (subtree.empty())
1557 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001558 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001559 "TrustedModuleRequiredToBoot");
1560 return;
1561 }
1562
1563 /* When there is more than one TPMEnable object... */
1564 if (subtree.size() > 1)
1565 {
Ed Tanous62598e32023-07-17 17:06:25 -07001566 BMCWEB_LOG_DEBUG(
1567 "DBUS response has more than 1 TPM Enable object:{}",
1568 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001569 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001570 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001571 return;
1572 }
1573
1574 // Make sure the Dbus response map has a service and objectPath
1575 // field
1576 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1577 {
Ed Tanous62598e32023-07-17 17:06:25 -07001578 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001579 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001580 return;
1581 }
1582
1583 const std::string& path = subtree[0].first;
1584 const std::string& serv = subtree[0].second.begin()->first;
1585
1586 if (serv.empty())
1587 {
Ed Tanous62598e32023-07-17 17:06:25 -07001588 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001589 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001590 return;
1591 }
1592
1593 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001594 sdbusplus::asio::setProperty(
1595 *crow::connections::systemBus, serv, path,
1596 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001597 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001598 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001599 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001600 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001601 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1602 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001603 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001604 return;
1605 }
Ed Tanous62598e32023-07-17 17:06:25 -07001606 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001607 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001608 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001609}
1610
1611/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301612 * @brief Sets boot properties into DBUS object(s).
1613 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001614 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001615 * @param[in] bootType The boot type to set.
1616 * @return Integer error code.
1617 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001618inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001619 const std::optional<std::string>& bootType)
1620{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001621 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001622
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001623 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001624 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001625 return;
1626 }
1627
1628 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001629 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001630 // Figure out which DBUS interface and property to use
1631 if (*bootType == "Legacy")
1632 {
1633 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1634 }
1635 else if (*bootType == "UEFI")
1636 {
1637 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1638 }
1639 else
1640 {
Ed Tanous62598e32023-07-17 17:06:25 -07001641 BMCWEB_LOG_DEBUG("Invalid property value for "
1642 "BootSourceOverrideMode: {}",
1643 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001644 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001645 "BootSourceOverrideMode");
1646 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001647 }
1648
1649 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001650 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001651
George Liu9ae226f2023-06-21 17:56:46 +08001652 sdbusplus::asio::setProperty(
1653 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1654 "/xyz/openbmc_project/control/host0/boot",
1655 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001656 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001657 if (ec)
1658 {
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 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001664 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001665 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001666 return;
1667 }
Ed Tanous62598e32023-07-17 17:06:25 -07001668 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001669 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001670}
1671
1672/**
1673 * @brief Sets boot properties into DBUS object(s).
1674 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001675 * @param[in] asyncResp Shared pointer for generating response
1676 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001677 * @param[in] bootType The boot type to set.
1678 * @return Integer error code.
1679 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001680inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001681 const std::optional<std::string>& bootEnable)
1682{
1683 if (!bootEnable)
1684 {
1685 return;
1686 }
1687 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001688 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001689
1690 bool bootOverrideEnable = false;
1691 bool bootOverridePersistent = false;
1692 // Figure out which DBUS interface and property to use
1693 if (*bootEnable == "Disabled")
1694 {
1695 bootOverrideEnable = false;
1696 }
1697 else if (*bootEnable == "Once")
1698 {
1699 bootOverrideEnable = true;
1700 bootOverridePersistent = false;
1701 }
1702 else if (*bootEnable == "Continuous")
1703 {
1704 bootOverrideEnable = true;
1705 bootOverridePersistent = true;
1706 }
1707 else
1708 {
Ed Tanous62598e32023-07-17 17:06:25 -07001709 BMCWEB_LOG_DEBUG(
1710 "Invalid property value for BootSourceOverrideEnabled: {}",
1711 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001712 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001713 "BootSourceOverrideEnabled");
1714 return;
1715 }
1716
1717 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001718 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001719
George Liu9ae226f2023-06-21 17:56:46 +08001720 sdbusplus::asio::setProperty(
1721 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1722 "/xyz/openbmc_project/control/host0/boot",
1723 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001724 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001725 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001726 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001727 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001728 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001729 return;
1730 }
Ed Tanous62598e32023-07-17 17:06:25 -07001731 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001732 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001733
1734 if (!bootOverrideEnable)
1735 {
1736 return;
1737 }
1738
1739 // In case boot override is enabled we need to set correct value for the
1740 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001741 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1742 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001743
George Liu9ae226f2023-06-21 17:56:46 +08001744 sdbusplus::asio::setProperty(
1745 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1746 "/xyz/openbmc_project/control/host0/boot/one_time",
1747 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001748 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001749 if (ec)
1750 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001751 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001752 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001753 return;
1754 }
Ed Tanous62598e32023-07-17 17:06:25 -07001755 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001756 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001757}
1758
1759/**
1760 * @brief Sets boot properties into DBUS object(s).
1761 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001762 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301763 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301764 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001765 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301766 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001767inline void
1768 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1769 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301770{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001771 std::string bootSourceStr;
1772 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001773
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001774 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301775 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001776 return;
1777 }
1778
1779 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001780 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001781 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001782 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1783 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001784 {
Ed Tanous62598e32023-07-17 17:06:25 -07001785 BMCWEB_LOG_DEBUG(
1786 "Invalid property value for BootSourceOverrideTarget: {}",
1787 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001788 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001789 "BootSourceTargetOverride");
1790 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001791 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301792
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001793 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001794 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1795 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001796
George Liu9ae226f2023-06-21 17:56:46 +08001797 sdbusplus::asio::setProperty(
1798 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1799 "/xyz/openbmc_project/control/host0/boot",
1800 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001801 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001802 if (ec)
1803 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001804 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001805 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001806 return;
1807 }
Ed Tanous62598e32023-07-17 17:06:25 -07001808 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001809 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001810
George Liu9ae226f2023-06-21 17:56:46 +08001811 sdbusplus::asio::setProperty(
1812 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1813 "/xyz/openbmc_project/control/host0/boot",
1814 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001815 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001816 if (ec)
1817 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001818 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001819 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001820 return;
1821 }
Ed Tanous62598e32023-07-17 17:06:25 -07001822 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001823 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001824}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001825
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001826/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001827 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301828 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001829 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301830 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001831 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301832 * @param[in] bootEnable The boot override enable from incoming RF request.
1833 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001834 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301835 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001836
Ed Tanousac106bf2023-06-07 09:24:59 -07001837inline void
1838 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1839 const std::optional<std::string>& bootSource,
1840 const std::optional<std::string>& bootType,
1841 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301842{
Ed Tanous62598e32023-07-17 17:06:25 -07001843 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301844
Ed Tanousac106bf2023-06-07 09:24:59 -07001845 setBootModeOrSource(asyncResp, bootSource);
1846 setBootType(asyncResp, bootType);
1847 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301848}
1849
George Liuc6a620f2020-04-10 17:18:11 +08001850/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001851 * @brief Sets AssetTag
1852 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001853 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001854 * @param[in] assetTag "AssetTag" from request.
1855 *
1856 * @return None.
1857 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001858inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001859 const std::string& assetTag)
1860{
George Liue99073f2022-12-09 11:06:16 +08001861 constexpr std::array<std::string_view, 1> interfaces = {
1862 "xyz.openbmc_project.Inventory.Item.System"};
1863 dbus::utility::getSubTree(
1864 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001865 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001866 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001867 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001868 if (ec)
1869 {
Ed Tanous62598e32023-07-17 17:06:25 -07001870 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001871 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001872 return;
1873 }
1874 if (subtree.empty())
1875 {
Ed Tanous62598e32023-07-17 17:06:25 -07001876 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001877 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001878 return;
1879 }
1880 // Assume only 1 system D-Bus object
1881 // Throw an error if there is more than 1
1882 if (subtree.size() > 1)
1883 {
Ed Tanous62598e32023-07-17 17:06:25 -07001884 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001885 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001886 return;
1887 }
1888 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1889 {
Ed Tanous62598e32023-07-17 17:06:25 -07001890 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001891 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001892 return;
1893 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001894
Ed Tanous002d39b2022-05-31 08:59:27 -07001895 const std::string& path = subtree[0].first;
1896 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001897
Ed Tanous002d39b2022-05-31 08:59:27 -07001898 if (service.empty())
1899 {
Ed Tanous62598e32023-07-17 17:06:25 -07001900 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001901 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001902 return;
1903 }
1904
George Liu9ae226f2023-06-21 17:56:46 +08001905 sdbusplus::asio::setProperty(
1906 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001907 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001908 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001909 if (ec2)
1910 {
1911 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1912 ec2);
1913 messages::internalError(asyncResp->res);
1914 return;
1915 }
George Liue99073f2022-12-09 11:06:16 +08001916 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001917 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001918}
1919
1920/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001921 * @brief Validate the specified stopBootOnFault is valid and return the
1922 * stopBootOnFault name associated with that string
1923 *
1924 * @param[in] stopBootOnFaultString String representing the desired
1925 * stopBootOnFault
1926 *
1927 * @return stopBootOnFault value or empty if incoming value is not valid
1928 */
1929inline std::optional<bool>
1930 validstopBootOnFault(const std::string& stopBootOnFaultString)
1931{
1932 if (stopBootOnFaultString == "AnyFault")
1933 {
1934 return true;
1935 }
1936
1937 if (stopBootOnFaultString == "Never")
1938 {
1939 return false;
1940 }
1941
1942 return std::nullopt;
1943}
1944
1945/**
1946 * @brief Sets stopBootOnFault
1947 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001948 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001949 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1950 *
1951 * @return None.
1952 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001953inline void
1954 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1955 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001956{
Ed Tanous62598e32023-07-17 17:06:25 -07001957 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001958
1959 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1960 if (!stopBootEnabled)
1961 {
Ed Tanous62598e32023-07-17 17:06:25 -07001962 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1963 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001964 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001965 "StopBootOnFault");
1966 return;
1967 }
1968
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001969 sdbusplus::asio::setProperty(
1970 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1971 "/xyz/openbmc_project/logging/settings",
1972 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1973 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001974 if (ec)
1975 {
1976 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001977 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001978 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1979 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001980 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001981 return;
1982 }
1983 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001984}
1985
1986/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001987 * @brief Sets automaticRetry (Auto Reboot)
1988 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001989 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001990 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1991 *
1992 * @return None.
1993 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001994inline void
1995 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1996 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001997{
Ed Tanous62598e32023-07-17 17:06:25 -07001998 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001999
2000 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002001 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002002
2003 if (automaticRetryConfig == "Disabled")
2004 {
2005 autoRebootEnabled = false;
2006 }
2007 else if (automaticRetryConfig == "RetryAttempts")
2008 {
2009 autoRebootEnabled = true;
2010 }
2011 else
2012 {
Ed Tanous62598e32023-07-17 17:06:25 -07002013 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
2014 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07002015 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002016 "AutomaticRetryConfig");
2017 return;
2018 }
2019
George Liu9ae226f2023-06-21 17:56:46 +08002020 sdbusplus::asio::setProperty(
2021 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002022 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002023 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002024 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002025 if (ec)
2026 {
2027 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2028 messages::internalError(asyncResp->res);
2029 return;
2030 }
2031 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002032}
2033
Ed Tanous8d69c662023-06-21 10:29:06 -07002034inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2035{
2036 if (policy == "AlwaysOn")
2037 {
2038 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2039 }
2040 if (policy == "AlwaysOff")
2041 {
2042 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2043 }
2044 if (policy == "LastState")
2045 {
2046 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2047 }
2048 return "";
2049}
2050
Gunnar Mills69f35302020-05-17 16:06:31 -05002051/**
George Liuc6a620f2020-04-10 17:18:11 +08002052 * @brief Sets power restore policy properties.
2053 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002054 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002055 * @param[in] policy power restore policy properties from request.
2056 *
2057 * @return None.
2058 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002059inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002060 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002061 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002062{
Ed Tanous62598e32023-07-17 17:06:25 -07002063 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002064
Ed Tanous8d69c662023-06-21 10:29:06 -07002065 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002066
Ed Tanous8d69c662023-06-21 10:29:06 -07002067 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002068 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002069 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002070 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002071 return;
2072 }
2073
George Liu9ae226f2023-06-21 17:56:46 +08002074 sdbusplus::asio::setProperty(
2075 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002076 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002077 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002078 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002079 if (ec)
2080 {
2081 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2082 messages::internalError(asyncResp->res);
2083 return;
2084 }
2085 });
George Liuc6a620f2020-04-10 17:18:11 +08002086}
2087
AppaRao Pulia6349912019-10-18 17:16:08 +05302088#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2089/**
2090 * @brief Retrieves provisioning status
2091 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002092 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302093 *
2094 * @return None.
2095 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002096inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302097{
Ed Tanous62598e32023-07-17 17:06:25 -07002098 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002099 sdbusplus::asio::getAllProperties(
2100 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2101 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002102 [asyncResp](const boost::system::error_code& ec,
2103 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002104 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002105 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2106 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002107 "#OemComputerSystem.OpenBmc";
2108 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002109
Ed Tanous002d39b2022-05-31 08:59:27 -07002110 if (ec)
2111 {
Ed Tanous62598e32023-07-17 17:06:25 -07002112 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002113 // not an error, don't have to have the interface
2114 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2115 return;
2116 }
2117
2118 const bool* provState = nullptr;
2119 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002120
2121 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002122 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2123 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002124
2125 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002126 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002127 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002128 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002129 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302130
Ed Tanous002d39b2022-05-31 08:59:27 -07002131 if ((provState == nullptr) || (lockState == nullptr))
2132 {
Ed Tanous62598e32023-07-17 17:06:25 -07002133 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002134 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002135 return;
2136 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302137
Ed Tanous002d39b2022-05-31 08:59:27 -07002138 if (*provState == true)
2139 {
2140 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302141 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002142 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302143 }
2144 else
2145 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002146 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302147 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002148 }
2149 else
2150 {
2151 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2152 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002153 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302154}
2155#endif
2156
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302157/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002158 * @brief Translate the PowerMode to a response message.
2159 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002160 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002161 * @param[in] modeValue PowerMode value to be translated
2162 *
2163 * @return None.
2164 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002165inline void
2166 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2167 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002168{
George Liu0fda0f12021-11-16 10:06:17 +08002169 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002170 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002171 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002172 }
George Liu0fda0f12021-11-16 10:06:17 +08002173 else if (
2174 modeValue ==
2175 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002176 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002177 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002178 }
George Liu0fda0f12021-11-16 10:06:17 +08002179 else if (modeValue ==
2180 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002181 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002182 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002183 }
George Liu0fda0f12021-11-16 10:06:17 +08002184 else if (modeValue ==
2185 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002186 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002187 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002188 }
2189 else
2190 {
2191 // Any other values would be invalid
Ed Tanous62598e32023-07-17 17:06:25 -07002192 BMCWEB_LOG_DEBUG("PowerMode value was not valid: {}", modeValue);
Ed Tanousac106bf2023-06-07 09:24:59 -07002193 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002194 }
2195}
2196
2197/**
2198 * @brief Retrieves system power mode
2199 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002200 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002201 *
2202 * @return None.
2203 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002204inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002205{
Ed Tanous62598e32023-07-17 17:06:25 -07002206 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002207
2208 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002209 constexpr std::array<std::string_view, 1> interfaces = {
2210 "xyz.openbmc_project.Control.Power.Mode"};
2211 dbus::utility::getSubTree(
2212 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002213 [asyncResp](const boost::system::error_code& ec,
2214 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002215 if (ec)
2216 {
Ed Tanous62598e32023-07-17 17:06:25 -07002217 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2218 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002219 // This is an optional D-Bus object so just return if
2220 // error occurs
2221 return;
2222 }
2223 if (subtree.empty())
2224 {
2225 // As noted above, this is an optional interface so just return
2226 // if there is no instance found
2227 return;
2228 }
2229 if (subtree.size() > 1)
2230 {
2231 // More then one PowerMode object is not supported and is an
2232 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002233 BMCWEB_LOG_DEBUG(
2234 "Found more than 1 system D-Bus Power.Mode objects: {}",
2235 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002236 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002237 return;
2238 }
2239 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2240 {
Ed Tanous62598e32023-07-17 17:06:25 -07002241 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002242 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002243 return;
2244 }
2245 const std::string& path = subtree[0].first;
2246 const std::string& service = subtree[0].second.begin()->first;
2247 if (service.empty())
2248 {
Ed Tanous62598e32023-07-17 17:06:25 -07002249 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002250 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002251 return;
2252 }
2253 // Valid Power Mode object found, now read the current value
2254 sdbusplus::asio::getProperty<std::string>(
2255 *crow::connections::systemBus, service, path,
2256 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002257 [asyncResp](const boost::system::error_code& ec2,
2258 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002259 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002260 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002261 BMCWEB_LOG_ERROR("DBUS response error on PowerMode Get: {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002262 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002263 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002264 return;
2265 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002266
Ed Tanousac106bf2023-06-07 09:24:59 -07002267 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002268 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002269
Ed Tanous62598e32023-07-17 17:06:25 -07002270 BMCWEB_LOG_DEBUG("Current power mode: {}", pmode);
Ed Tanousac106bf2023-06-07 09:24:59 -07002271 translatePowerMode(asyncResp, pmode);
George Liue99073f2022-12-09 11:06:16 +08002272 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002273 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002274}
2275
2276/**
2277 * @brief Validate the specified mode is valid and return the PowerMode
2278 * name associated with that string
2279 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002280 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002281 * @param[in] modeString String representing the desired PowerMode
2282 *
2283 * @return PowerMode value or empty string if mode is not valid
2284 */
2285inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002286 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002287 const std::string& modeString)
2288{
2289 std::string mode;
2290
2291 if (modeString == "Static")
2292 {
2293 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2294 }
2295 else if (modeString == "MaximumPerformance")
2296 {
George Liu0fda0f12021-11-16 10:06:17 +08002297 mode =
2298 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002299 }
2300 else if (modeString == "PowerSaving")
2301 {
2302 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2303 }
2304 else
2305 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002306 messages::propertyValueNotInList(asyncResp->res, modeString,
2307 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002308 }
2309 return mode;
2310}
2311
2312/**
2313 * @brief Sets system power mode.
2314 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002315 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002316 * @param[in] pmode System power mode from request.
2317 *
2318 * @return None.
2319 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002320inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002321 const std::string& pmode)
2322{
Ed Tanous62598e32023-07-17 17:06:25 -07002323 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002324
Ed Tanousac106bf2023-06-07 09:24:59 -07002325 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002326 if (powerMode.empty())
2327 {
2328 return;
2329 }
2330
2331 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002332 constexpr std::array<std::string_view, 1> interfaces = {
2333 "xyz.openbmc_project.Control.Power.Mode"};
2334 dbus::utility::getSubTree(
2335 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002336 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002337 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002338 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002339 if (ec)
2340 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002341 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002342 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002343 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002344 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002345 return;
2346 }
2347 if (subtree.empty())
2348 {
2349 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002350 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002351 "PowerMode");
2352 return;
2353 }
2354 if (subtree.size() > 1)
2355 {
2356 // More then one PowerMode object is not supported and is an
2357 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002358 BMCWEB_LOG_DEBUG(
2359 "Found more than 1 system D-Bus Power.Mode objects: {}",
2360 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002361 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002362 return;
2363 }
2364 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2365 {
Ed Tanous62598e32023-07-17 17:06:25 -07002366 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002367 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002368 return;
2369 }
2370 const std::string& path = subtree[0].first;
2371 const std::string& service = subtree[0].second.begin()->first;
2372 if (service.empty())
2373 {
Ed Tanous62598e32023-07-17 17:06:25 -07002374 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002375 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002376 return;
2377 }
2378
Ed Tanous62598e32023-07-17 17:06:25 -07002379 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002380
2381 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002382 sdbusplus::asio::setProperty(
2383 *crow::connections::systemBus, service, path,
2384 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002385 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002386 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002387 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002388 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002389 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002390 return;
2391 }
George Liue99073f2022-12-09 11:06:16 +08002392 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002393 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002394}
2395
2396/**
Yong Li51709ff2019-09-30 14:13:04 +08002397 * @brief Translates watchdog timeout action DBUS property value to redfish.
2398 *
2399 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2400 *
2401 * @return Returns as a string, the timeout action in Redfish terms. If
2402 * translation cannot be done, returns an empty string.
2403 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002404inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002405{
2406 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2407 {
2408 return "None";
2409 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002410 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002411 {
2412 return "ResetSystem";
2413 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002414 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002415 {
2416 return "PowerDown";
2417 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002418 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002419 {
2420 return "PowerCycle";
2421 }
2422
2423 return "";
2424}
2425
2426/**
Yong Lic45f0082019-10-10 14:19:01 +08002427 *@brief Translates timeout action from Redfish to DBUS property value.
2428 *
2429 *@param[in] rfAction The timeout action in Redfish.
2430 *
2431 *@return Returns as a string, the time_out action as expected by DBUS.
2432 *If translation cannot be done, returns an empty string.
2433 */
2434
Ed Tanous23a21a12020-07-25 04:45:05 +00002435inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002436{
2437 if (rfAction == "None")
2438 {
2439 return "xyz.openbmc_project.State.Watchdog.Action.None";
2440 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002441 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002442 {
2443 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2444 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002445 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002446 {
2447 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2448 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002449 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002450 {
2451 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2452 }
2453
2454 return "";
2455}
2456
2457/**
Yong Li51709ff2019-09-30 14:13:04 +08002458 * @brief Retrieves host watchdog timer properties over DBUS
2459 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002460 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002461 *
2462 * @return None.
2463 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002464inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002465 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002466{
Ed Tanous62598e32023-07-17 17:06:25 -07002467 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002468 sdbusplus::asio::getAllProperties(
2469 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2470 "/xyz/openbmc_project/watchdog/host0",
2471 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002472 [asyncResp](const boost::system::error_code& ec,
2473 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002474 if (ec)
2475 {
2476 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002477 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002478 return;
2479 }
2480
Ed Tanous62598e32023-07-17 17:06:25 -07002481 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002482
2483 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002484 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002485
2486 // watchdog service is running/enabled
2487 hostWatchdogTimer["Status"]["State"] = "Enabled";
2488
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002489 const bool* enabled = nullptr;
2490 const std::string* expireAction = nullptr;
2491
2492 const bool success = sdbusplus::unpackPropertiesNoThrow(
2493 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2494 "ExpireAction", expireAction);
2495
2496 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002497 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002498 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002499 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002500 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002501
2502 if (enabled != nullptr)
2503 {
2504 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2505 }
2506
2507 if (expireAction != nullptr)
2508 {
2509 std::string action = dbusToRfWatchdogAction(*expireAction);
2510 if (action.empty())
2511 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002512 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002513 return;
2514 }
2515 hostWatchdogTimer["TimeoutAction"] = action;
2516 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002517 });
Yong Li51709ff2019-09-30 14:13:04 +08002518}
2519
2520/**
Yong Lic45f0082019-10-10 14:19:01 +08002521 * @brief Sets Host WatchDog Timer properties.
2522 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002523 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002524 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2525 * RF request.
2526 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2527 *
2528 * @return None.
2529 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002530inline void
2531 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2532 const std::optional<bool> wdtEnable,
2533 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002534{
Ed Tanous62598e32023-07-17 17:06:25 -07002535 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002536
2537 if (wdtTimeOutAction)
2538 {
2539 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2540 // check if TimeOut Action is Valid
2541 if (wdtTimeOutActStr.empty())
2542 {
Ed Tanous62598e32023-07-17 17:06:25 -07002543 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2544 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002545 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002546 "TimeoutAction");
2547 return;
2548 }
2549
George Liu9ae226f2023-06-21 17:56:46 +08002550 sdbusplus::asio::setProperty(
2551 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002552 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002553 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002554 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002555 if (ec)
2556 {
2557 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2558 messages::internalError(asyncResp->res);
2559 return;
2560 }
2561 });
Yong Lic45f0082019-10-10 14:19:01 +08002562 }
2563
2564 if (wdtEnable)
2565 {
George Liu9ae226f2023-06-21 17:56:46 +08002566 sdbusplus::asio::setProperty(
2567 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2568 "/xyz/openbmc_project/watchdog/host0",
2569 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002570 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002571 if (ec)
2572 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002573 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002574 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002575 return;
2576 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002577 });
Yong Lic45f0082019-10-10 14:19:01 +08002578 }
2579}
2580
Chris Cain37bbf982021-09-20 10:53:09 -05002581/**
2582 * @brief Parse the Idle Power Saver properties into json
2583 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002584 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002585 * @param[in] properties IPS property data from DBus.
2586 *
2587 * @return true if successful
2588 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002589inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002590 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002591 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002592{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002593 const bool* enabled = nullptr;
2594 const uint8_t* enterUtilizationPercent = nullptr;
2595 const uint64_t* enterDwellTime = nullptr;
2596 const uint8_t* exitUtilizationPercent = nullptr;
2597 const uint64_t* exitDwellTime = nullptr;
2598
2599 const bool success = sdbusplus::unpackPropertiesNoThrow(
2600 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002601 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2602 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2603 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002604
2605 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002606 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002607 return false;
2608 }
2609
2610 if (enabled != nullptr)
2611 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002612 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002613 }
2614
2615 if (enterUtilizationPercent != nullptr)
2616 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002617 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002618 *enterUtilizationPercent;
2619 }
2620
2621 if (enterDwellTime != nullptr)
2622 {
2623 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002624 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002625 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2626 .count();
2627 }
2628
2629 if (exitUtilizationPercent != nullptr)
2630 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002631 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002632 *exitUtilizationPercent;
2633 }
2634
2635 if (exitDwellTime != nullptr)
2636 {
2637 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002638 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002639 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2640 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002641 }
2642
2643 return true;
2644}
2645
2646/**
2647 * @brief Retrieves host watchdog timer properties over DBUS
2648 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002649 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002650 *
2651 * @return None.
2652 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002653inline void
2654 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002655{
Ed Tanous62598e32023-07-17 17:06:25 -07002656 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002657
2658 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002659 constexpr std::array<std::string_view, 1> interfaces = {
2660 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2661 dbus::utility::getSubTree(
2662 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002663 [asyncResp](const boost::system::error_code& ec,
2664 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002665 if (ec)
2666 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002667 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002668 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2669 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002670 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002671 return;
2672 }
2673 if (subtree.empty())
2674 {
2675 // This is an optional interface so just return
2676 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002677 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002678 return;
2679 }
2680 if (subtree.size() > 1)
2681 {
2682 // More then one PowerIdlePowerSaver object is not supported and
2683 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002684 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2685 "Power.IdlePowerSaver objects: {}",
2686 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002687 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002688 return;
2689 }
2690 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2691 {
Ed Tanous62598e32023-07-17 17:06:25 -07002692 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002693 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002694 return;
2695 }
2696 const std::string& path = subtree[0].first;
2697 const std::string& service = subtree[0].second.begin()->first;
2698 if (service.empty())
2699 {
Ed Tanous62598e32023-07-17 17:06:25 -07002700 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002701 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002702 return;
2703 }
2704
2705 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002706 sdbusplus::asio::getAllProperties(
2707 *crow::connections::systemBus, service, path,
2708 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002709 [asyncResp](const boost::system::error_code& ec2,
2710 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002711 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002712 {
Ed Tanous62598e32023-07-17 17:06:25 -07002713 BMCWEB_LOG_ERROR(
2714 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002715 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002716 return;
2717 }
2718
Ed Tanousac106bf2023-06-07 09:24:59 -07002719 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002720 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002721 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002722 return;
2723 }
George Liue99073f2022-12-09 11:06:16 +08002724 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002725 });
Chris Cain37bbf982021-09-20 10:53:09 -05002726
Ed Tanous62598e32023-07-17 17:06:25 -07002727 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002728}
2729
2730/**
2731 * @brief Sets Idle Power Saver properties.
2732 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002733 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002734 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2735 * RF request.
2736 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2737 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2738 * before entering idle state.
2739 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2740 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2741 * before exiting idle state
2742 *
2743 * @return None.
2744 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002745inline void
2746 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2747 const std::optional<bool> ipsEnable,
2748 const std::optional<uint8_t> ipsEnterUtil,
2749 const std::optional<uint64_t> ipsEnterTime,
2750 const std::optional<uint8_t> ipsExitUtil,
2751 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002752{
Ed Tanous62598e32023-07-17 17:06:25 -07002753 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002754
2755 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002756 constexpr std::array<std::string_view, 1> interfaces = {
2757 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2758 dbus::utility::getSubTree(
2759 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002760 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002761 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002762 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002763 if (ec)
2764 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002765 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002766 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2767 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002768 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002769 return;
2770 }
2771 if (subtree.empty())
2772 {
2773 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002774 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002775 "IdlePowerSaver");
2776 return;
2777 }
2778 if (subtree.size() > 1)
2779 {
2780 // More then one PowerIdlePowerSaver object is not supported and
2781 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002782 BMCWEB_LOG_DEBUG(
2783 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2784 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002785 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002786 return;
2787 }
2788 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2789 {
Ed Tanous62598e32023-07-17 17:06:25 -07002790 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002791 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002792 return;
2793 }
2794 const std::string& path = subtree[0].first;
2795 const std::string& service = subtree[0].second.begin()->first;
2796 if (service.empty())
2797 {
Ed Tanous62598e32023-07-17 17:06:25 -07002798 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002799 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002800 return;
2801 }
Chris Cain37bbf982021-09-20 10:53:09 -05002802
Ed Tanous002d39b2022-05-31 08:59:27 -07002803 // Valid Power IdlePowerSaver object found, now set any values that
2804 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002805
Ed Tanous002d39b2022-05-31 08:59:27 -07002806 if (ipsEnable)
2807 {
George Liu9ae226f2023-06-21 17:56:46 +08002808 sdbusplus::asio::setProperty(
2809 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002810 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002811 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002812 if (ec2)
2813 {
2814 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2815 messages::internalError(asyncResp->res);
2816 return;
2817 }
2818 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002819 }
2820 if (ipsEnterUtil)
2821 {
George Liu9ae226f2023-06-21 17:56:46 +08002822 sdbusplus::asio::setProperty(
2823 *crow::connections::systemBus, service, path,
2824 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2825 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002826 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002827 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002828 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002829 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002830 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002831 return;
2832 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002833 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002834 }
2835 if (ipsEnterTime)
2836 {
2837 // Convert from seconds into milliseconds for DBus
2838 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002839 sdbusplus::asio::setProperty(
2840 *crow::connections::systemBus, service, path,
2841 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2842 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002843 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002844 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002845 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002846 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002847 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002848 return;
2849 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002850 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002851 }
2852 if (ipsExitUtil)
2853 {
George Liu9ae226f2023-06-21 17:56:46 +08002854 sdbusplus::asio::setProperty(
2855 *crow::connections::systemBus, service, path,
2856 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2857 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002858 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002859 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002860 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002861 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002862 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002863 return;
2864 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002865 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002866 }
2867 if (ipsExitTime)
2868 {
2869 // Convert from seconds into milliseconds for DBus
2870 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002871 sdbusplus::asio::setProperty(
2872 *crow::connections::systemBus, service, path,
2873 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2874 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002875 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002876 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002877 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002878 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002879 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002880 return;
2881 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002882 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002883 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002884 });
Chris Cain37bbf982021-09-20 10:53:09 -05002885
Ed Tanous62598e32023-07-17 17:06:25 -07002886 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002887}
2888
Ed Tanousc1e219d2023-06-07 10:34:33 -07002889inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002890 crow::App& app, const crow::Request& req,
2891 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2892{
2893 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2894 {
2895 return;
2896 }
2897 asyncResp->res.addHeader(
2898 boost::beast::http::field::link,
2899 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2900}
2901
Ed Tanousc1e219d2023-06-07 10:34:33 -07002902inline void handleComputerSystemCollectionGet(
2903 crow::App& app, const crow::Request& req,
2904 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2905{
2906 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2907 {
2908 return;
2909 }
2910
2911 asyncResp->res.addHeader(
2912 boost::beast::http::field::link,
2913 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2914 asyncResp->res.jsonValue["@odata.type"] =
2915 "#ComputerSystemCollection.ComputerSystemCollection";
2916 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2917 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2918
2919 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2920 ifaceArray = nlohmann::json::array();
2921 if constexpr (bmcwebEnableMultiHost)
2922 {
2923 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2924 // Option currently returns no systems. TBD
2925 return;
2926 }
2927 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2928 nlohmann::json::object_t system;
2929 system["@odata.id"] = "/redfish/v1/Systems/system";
2930 ifaceArray.emplace_back(std::move(system));
2931 sdbusplus::asio::getProperty<std::string>(
2932 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2933 "/xyz/openbmc_project/network/hypervisor",
2934 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2935 [asyncResp](const boost::system::error_code& ec2,
2936 const std::string& /*hostName*/) {
2937 if (ec2)
2938 {
2939 return;
2940 }
2941 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2942 if (val == asyncResp->res.jsonValue.end())
2943 {
Ed Tanous62598e32023-07-17 17:06:25 -07002944 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002945 return;
2946 }
2947 uint64_t* count = val->get_ptr<uint64_t*>();
2948 if (count == nullptr)
2949 {
Ed Tanous62598e32023-07-17 17:06:25 -07002950 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002951 return;
2952 }
2953 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07002954 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002955 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2956 nlohmann::json::object_t hypervisor;
2957 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2958 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05002959 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07002960}
2961
Yong Lic45f0082019-10-10 14:19:01 +08002962/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002963 * Function transceives data with dbus directly.
2964 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002965inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002966{
Patrick Williams89492a12023-05-10 07:51:34 -05002967 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2968 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2969 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002970 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002971 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002972
2973 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002974 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002975 if (ec)
2976 {
Ed Tanous62598e32023-07-17 17:06:25 -07002977 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002978 messages::internalError(asyncResp->res);
2979 return;
2980 }
2981 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05002982 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002983 serviceName, objectPath, interfaceName, method);
2984}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002985
2986/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002987 * Handle error responses from d-bus for system power requests
2988 */
2989inline void handleSystemActionResetError(const boost::system::error_code& ec,
2990 const sdbusplus::message_t& eMsg,
2991 std::string_view resetType,
2992 crow::Response& res)
2993{
2994 if (ec.value() == boost::asio::error::invalid_argument)
2995 {
2996 messages::actionParameterNotSupported(res, resetType, "Reset");
2997 return;
2998 }
2999
3000 if (eMsg.get_error() == nullptr)
3001 {
Ed Tanous62598e32023-07-17 17:06:25 -07003002 BMCWEB_LOG_ERROR("D-Bus response error: {}", ec);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003003 messages::internalError(res);
3004 return;
3005 }
3006 std::string_view errorMessage = eMsg.get_error()->name;
3007
3008 // If operation failed due to BMC not being in Ready state, tell
3009 // user to retry in a bit
3010 if ((errorMessage ==
3011 std::string_view(
3012 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3013 (errorMessage ==
3014 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3015 {
Ed Tanous62598e32023-07-17 17:06:25 -07003016 BMCWEB_LOG_DEBUG("BMC not ready, operation not allowed right now");
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003017 messages::serviceTemporarilyUnavailable(res, "10");
3018 return;
3019 }
3020
Ed Tanous62598e32023-07-17 17:06:25 -07003021 BMCWEB_LOG_ERROR("System Action Reset transition fail {} sdbusplus:{}", ec,
3022 errorMessage);
Andrew Geisslerfc903b32023-05-31 14:15:42 -04003023 messages::internalError(res);
3024}
3025
Ed Tanousc1e219d2023-06-07 10:34:33 -07003026inline void handleComputerSystemResetActionPost(
3027 crow::App& app, const crow::Request& req,
3028 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3029 const std::string& systemName)
3030{
3031 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3032 {
3033 return;
3034 }
3035 if (systemName != "system")
3036 {
3037 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3038 systemName);
3039 return;
3040 }
3041 if constexpr (bmcwebEnableMultiHost)
3042 {
3043 // Option currently returns no systems. TBD
3044 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3045 systemName);
3046 return;
3047 }
3048 std::string resetType;
3049 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3050 {
3051 return;
3052 }
3053
3054 // Get the command and host vs. chassis
3055 std::string command;
3056 bool hostCommand = true;
3057 if ((resetType == "On") || (resetType == "ForceOn"))
3058 {
3059 command = "xyz.openbmc_project.State.Host.Transition.On";
3060 hostCommand = true;
3061 }
3062 else if (resetType == "ForceOff")
3063 {
3064 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3065 hostCommand = false;
3066 }
3067 else if (resetType == "ForceRestart")
3068 {
3069 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3070 hostCommand = true;
3071 }
3072 else if (resetType == "GracefulShutdown")
3073 {
3074 command = "xyz.openbmc_project.State.Host.Transition.Off";
3075 hostCommand = true;
3076 }
3077 else if (resetType == "GracefulRestart")
3078 {
3079 command =
3080 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3081 hostCommand = true;
3082 }
3083 else if (resetType == "PowerCycle")
3084 {
3085 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3086 hostCommand = true;
3087 }
3088 else if (resetType == "Nmi")
3089 {
3090 doNMI(asyncResp);
3091 return;
3092 }
3093 else
3094 {
3095 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3096 return;
3097 }
3098
3099 if (hostCommand)
3100 {
George Liu9ae226f2023-06-21 17:56:46 +08003101 sdbusplus::asio::setProperty(
3102 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3103 "/xyz/openbmc_project/state/host0",
3104 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3105 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003106 [asyncResp, resetType](const boost::system::error_code& ec,
3107 sdbusplus::message_t& sdbusErrMsg) {
3108 if (ec)
3109 {
3110 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3111 asyncResp->res);
3112
3113 return;
3114 }
3115 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003116 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003117 }
3118 else
3119 {
George Liu9ae226f2023-06-21 17:56:46 +08003120 sdbusplus::asio::setProperty(
3121 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3122 "/xyz/openbmc_project/state/chassis0",
3123 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3124 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003125 [asyncResp, resetType](const boost::system::error_code& ec,
3126 sdbusplus::message_t& sdbusErrMsg) {
3127 if (ec)
3128 {
3129 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3130 asyncResp->res);
3131 return;
3132 }
3133 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05003134 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003135 }
3136}
3137
Ed Tanousc1e219d2023-06-07 10:34:33 -07003138inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003139 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003140 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3141 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003142{
3143 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3144 {
3145 return;
3146 }
3147
3148 asyncResp->res.addHeader(
3149 boost::beast::http::field::link,
3150 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3151}
3152
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003153inline void afterPortRequest(
3154 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3155 const boost::system::error_code& ec,
3156 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3157{
3158 if (ec)
3159 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003160 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003161 messages::internalError(asyncResp->res);
3162 return;
3163 }
3164 for (const auto& data : socketData)
3165 {
3166 const std::string& socketPath = get<0>(data);
3167 const std::string& protocolName = get<1>(data);
3168 bool isProtocolEnabled = get<2>(data);
3169 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3170 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3171 // need to retrieve port number for
3172 // obmc-console-ssh service
3173 if (protocolName == "SSH")
3174 {
3175 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003176 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003177 int portNumber) {
3178 if (ec1)
3179 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003180 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003181 messages::internalError(asyncResp->res);
3182 return;
3183 }
3184 nlohmann::json& dataJson1 =
3185 asyncResp->res.jsonValue["SerialConsole"];
3186 dataJson1[protocolName]["Port"] = portNumber;
3187 });
3188 }
3189 }
3190}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003191
3192inline void
3193 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3194 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3195 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003196{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003197 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3198 {
3199 return;
3200 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003201
Ed Tanousc1e219d2023-06-07 10:34:33 -07003202 if constexpr (bmcwebEnableMultiHost)
3203 {
3204 // Option currently returns no systems. TBD
3205 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3206 systemName);
3207 return;
3208 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003209
Ed Tanousc1e219d2023-06-07 10:34:33 -07003210 if (systemName == "hypervisor")
3211 {
3212 handleHypervisorSystemGet(asyncResp);
3213 return;
3214 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003215
Ed Tanousc1e219d2023-06-07 10:34:33 -07003216 if (systemName != "system")
3217 {
3218 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3219 systemName);
3220 return;
3221 }
3222 asyncResp->res.addHeader(
3223 boost::beast::http::field::link,
3224 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3225 asyncResp->res.jsonValue["@odata.type"] =
3226 "#ComputerSystem.v1_16_0.ComputerSystem";
3227 asyncResp->res.jsonValue["Name"] = "system";
3228 asyncResp->res.jsonValue["Id"] = "system";
3229 asyncResp->res.jsonValue["SystemType"] = "Physical";
3230 asyncResp->res.jsonValue["Description"] = "Computer System";
3231 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3232 if constexpr (bmcwebEnableProcMemStatus)
3233 {
3234 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3235 "Disabled";
3236 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3237 "Disabled";
3238 }
3239 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003240 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003241 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003242
Ed Tanousc1e219d2023-06-07 10:34:33 -07003243 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3244 "/redfish/v1/Systems/system/Processors";
3245 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3246 "/redfish/v1/Systems/system/Memory";
3247 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3248 "/redfish/v1/Systems/system/Storage";
3249 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3250 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003251
Ed Tanousc1e219d2023-06-07 10:34:33 -07003252 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3253 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3254 asyncResp->res
3255 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3256 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003257
Ed Tanousc1e219d2023-06-07 10:34:33 -07003258 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3259 "/redfish/v1/Systems/system/LogServices";
3260 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3261 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003262
Ed Tanousc1e219d2023-06-07 10:34:33 -07003263 nlohmann::json::array_t managedBy;
3264 nlohmann::json& manager = managedBy.emplace_back();
3265 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3266 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3267 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3268 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003269
Ed Tanousc1e219d2023-06-07 10:34:33 -07003270 // Fill in SerialConsole info
3271 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3272 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003273
Ed Tanousc1e219d2023-06-07 10:34:33 -07003274 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3275 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3276 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3277 "Press ~. to exit console";
3278 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3279 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003280
3281#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003282 // Fill in GraphicalConsole info
3283 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3284 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3285 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3286 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003287
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003288#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003289
Ed Tanousc1e219d2023-06-07 10:34:33 -07003290 auto health = std::make_shared<HealthPopulate>(asyncResp);
3291 if constexpr (bmcwebEnableHealthPopulate)
3292 {
3293 constexpr std::array<std::string_view, 4> inventoryForSystems{
3294 "xyz.openbmc_project.Inventory.Item.Dimm",
3295 "xyz.openbmc_project.Inventory.Item.Cpu",
3296 "xyz.openbmc_project.Inventory.Item.Drive",
3297 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003298
Ed Tanousc1e219d2023-06-07 10:34:33 -07003299 dbus::utility::getSubTreePaths(
3300 "/", 0, inventoryForSystems,
3301 [health](const boost::system::error_code& ec,
3302 const std::vector<std::string>& resp) {
3303 if (ec)
3304 {
3305 // no inventory
3306 return;
3307 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003308
Ed Tanousc1e219d2023-06-07 10:34:33 -07003309 health->inventory = resp;
Patrick Williams5a39f772023-10-20 11:20:21 -05003310 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003311 health->populate();
3312 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003313
Ed Tanousc1e219d2023-06-07 10:34:33 -07003314 getMainChassisId(asyncResp,
3315 [](const std::string& chassisId,
3316 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3317 nlohmann::json::array_t chassisArray;
3318 nlohmann::json& chassis = chassisArray.emplace_back();
3319 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3320 chassisId);
3321 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3322 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003323
Ed Tanousc1e219d2023-06-07 10:34:33 -07003324 getLocationIndicatorActive(asyncResp);
3325 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3326 getIndicatorLedState(asyncResp);
3327 getComputerSystem(asyncResp, health);
3328 getHostState(asyncResp);
3329 getBootProperties(asyncResp);
3330 getBootProgress(asyncResp);
3331 getBootProgressLastStateTime(asyncResp);
3332 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3333 getHostWatchdogTimer(asyncResp);
3334 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003335 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003336 getAutomaticRetryPolicy(asyncResp);
3337 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003338#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003339 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003340#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003341 getTrustedModuleRequiredToBoot(asyncResp);
3342 getPowerMode(asyncResp);
3343 getIdlePowerSaver(asyncResp);
3344}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003345
Ed Tanousc1e219d2023-06-07 10:34:33 -07003346inline void handleComputerSystemPatch(
3347 crow::App& app, const crow::Request& req,
3348 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3349 const std::string& systemName)
3350{
3351 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3352 {
3353 return;
3354 }
3355 if constexpr (bmcwebEnableMultiHost)
3356 {
3357 // Option currently returns no systems. TBD
3358 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3359 systemName);
3360 return;
3361 }
3362 if (systemName != "system")
3363 {
3364 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3365 systemName);
3366 return;
3367 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003368
Ed Tanousc1e219d2023-06-07 10:34:33 -07003369 asyncResp->res.addHeader(
3370 boost::beast::http::field::link,
3371 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003372
Ed Tanousc1e219d2023-06-07 10:34:33 -07003373 std::optional<bool> locationIndicatorActive;
3374 std::optional<std::string> indicatorLed;
3375 std::optional<std::string> assetTag;
3376 std::optional<std::string> powerRestorePolicy;
3377 std::optional<std::string> powerMode;
3378 std::optional<bool> wdtEnable;
3379 std::optional<std::string> wdtTimeOutAction;
3380 std::optional<std::string> bootSource;
3381 std::optional<std::string> bootType;
3382 std::optional<std::string> bootEnable;
3383 std::optional<std::string> bootAutomaticRetry;
3384 std::optional<uint32_t> bootAutomaticRetryAttempts;
3385 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003386 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003387 std::optional<bool> ipsEnable;
3388 std::optional<uint8_t> ipsEnterUtil;
3389 std::optional<uint64_t> ipsEnterTime;
3390 std::optional<uint8_t> ipsExitUtil;
3391 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003392
Ed Tanousc1e219d2023-06-07 10:34:33 -07003393 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003394 if (!json_util::readJsonPatch(
3395 req, asyncResp->res,
3396 "IndicatorLED", indicatorLed,
3397 "LocationIndicatorActive", locationIndicatorActive,
3398 "AssetTag", assetTag,
3399 "PowerRestorePolicy", powerRestorePolicy,
3400 "PowerMode", powerMode,
3401 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3402 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3403 "Boot/BootSourceOverrideTarget", bootSource,
3404 "Boot/BootSourceOverrideMode", bootType,
3405 "Boot/BootSourceOverrideEnabled", bootEnable,
3406 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003407 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003408 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003409 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003410 "IdlePowerSaver/Enabled", ipsEnable,
3411 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3412 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3413 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3414 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3415 {
3416 return;
3417 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003418 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003419
Ed Tanousc1e219d2023-06-07 10:34:33 -07003420 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003421
Ed Tanousc1e219d2023-06-07 10:34:33 -07003422 if (assetTag)
3423 {
3424 setAssetTag(asyncResp, *assetTag);
3425 }
James Feistb49ac872019-05-21 15:12:01 -07003426
Ed Tanousc1e219d2023-06-07 10:34:33 -07003427 if (wdtEnable || wdtTimeOutAction)
3428 {
3429 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3430 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003431
Ed Tanousc1e219d2023-06-07 10:34:33 -07003432 if (bootSource || bootType || bootEnable)
3433 {
3434 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3435 }
3436 if (bootAutomaticRetry)
3437 {
3438 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3439 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003440
Ed Tanousc1e219d2023-06-07 10:34:33 -07003441 if (bootAutomaticRetryAttempts)
3442 {
3443 setAutomaticRetryAttempts(asyncResp,
3444 bootAutomaticRetryAttempts.value());
3445 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003446
Ed Tanousc1e219d2023-06-07 10:34:33 -07003447 if (bootTrustedModuleRequired)
3448 {
3449 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3450 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003451
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003452 if (stopBootOnFault)
3453 {
3454 setStopBootOnFault(asyncResp, *stopBootOnFault);
3455 }
3456
Ed Tanousc1e219d2023-06-07 10:34:33 -07003457 if (locationIndicatorActive)
3458 {
3459 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3460 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003461
Ed Tanousc1e219d2023-06-07 10:34:33 -07003462 // TODO (Gunnar): Remove IndicatorLED after enough time has
3463 // passed
3464 if (indicatorLed)
3465 {
3466 setIndicatorLedState(asyncResp, *indicatorLed);
3467 asyncResp->res.addHeader(boost::beast::http::field::warning,
3468 "299 - \"IndicatorLED is deprecated. Use "
3469 "LocationIndicatorActive instead.\"");
3470 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003471
Ed Tanousc1e219d2023-06-07 10:34:33 -07003472 if (powerRestorePolicy)
3473 {
3474 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3475 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003476
Ed Tanousc1e219d2023-06-07 10:34:33 -07003477 if (powerMode)
3478 {
3479 setPowerMode(asyncResp, *powerMode);
3480 }
Chris Cain37bbf982021-09-20 10:53:09 -05003481
Ed Tanousc1e219d2023-06-07 10:34:33 -07003482 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3483 {
3484 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3485 ipsExitUtil, ipsExitTime);
3486 }
3487}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303488
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003489inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003490 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003491 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003492 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003493{
3494 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3495 {
3496 return;
3497 }
3498 asyncResp->res.addHeader(
3499 boost::beast::http::field::link,
3500 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3501}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003502inline void handleSystemCollectionResetActionGet(
3503 crow::App& app, const crow::Request& req,
3504 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3505 const std::string& systemName)
3506{
3507 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3508 {
3509 return;
3510 }
3511 if constexpr (bmcwebEnableMultiHost)
3512 {
3513 // Option currently returns no systems. TBD
3514 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3515 systemName);
3516 return;
3517 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003518
Ed Tanousc1e219d2023-06-07 10:34:33 -07003519 if (systemName == "hypervisor")
3520 {
3521 handleHypervisorResetActionGet(asyncResp);
3522 return;
3523 }
3524
3525 if (systemName != "system")
3526 {
3527 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3528 systemName);
3529 return;
3530 }
3531
3532 asyncResp->res.addHeader(
3533 boost::beast::http::field::link,
3534 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3535
3536 asyncResp->res.jsonValue["@odata.id"] =
3537 "/redfish/v1/Systems/system/ResetActionInfo";
3538 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3539 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3540 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3541
3542 nlohmann::json::array_t parameters;
3543 nlohmann::json::object_t parameter;
3544
3545 parameter["Name"] = "ResetType";
3546 parameter["Required"] = true;
3547 parameter["DataType"] = "String";
3548 nlohmann::json::array_t allowableValues;
3549 allowableValues.emplace_back("On");
3550 allowableValues.emplace_back("ForceOff");
3551 allowableValues.emplace_back("ForceOn");
3552 allowableValues.emplace_back("ForceRestart");
3553 allowableValues.emplace_back("GracefulRestart");
3554 allowableValues.emplace_back("GracefulShutdown");
3555 allowableValues.emplace_back("PowerCycle");
3556 allowableValues.emplace_back("Nmi");
3557 parameter["AllowableValues"] = std::move(allowableValues);
3558 parameters.emplace_back(std::move(parameter));
3559
3560 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3561}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303562/**
3563 * SystemResetActionInfo derived class for delivering Computer Systems
3564 * ResetType AllowableValues using ResetInfo schema.
3565 */
Ed Tanous100afe52023-06-07 13:30:46 -07003566inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303567{
Ed Tanous100afe52023-06-07 13:30:46 -07003568 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3569 .privileges(redfish::privileges::headComputerSystemCollection)
3570 .methods(boost::beast::http::verb::head)(
3571 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3572
3573 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3574 .privileges(redfish::privileges::getComputerSystemCollection)
3575 .methods(boost::beast::http::verb::get)(
3576 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3577
3578 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3579 .privileges(redfish::privileges::headComputerSystem)
3580 .methods(boost::beast::http::verb::head)(
3581 std::bind_front(handleComputerSystemHead, std::ref(app)));
3582
3583 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3584 .privileges(redfish::privileges::getComputerSystem)
3585 .methods(boost::beast::http::verb::get)(
3586 std::bind_front(handleComputerSystemGet, std::ref(app)));
3587
3588 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3589 .privileges(redfish::privileges::patchComputerSystem)
3590 .methods(boost::beast::http::verb::patch)(
3591 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3592
3593 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3594 .privileges(redfish::privileges::postComputerSystem)
3595 .methods(boost::beast::http::verb::post)(std::bind_front(
3596 handleComputerSystemResetActionPost, std::ref(app)));
3597
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003598 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003599 .privileges(redfish::privileges::headActionInfo)
3600 .methods(boost::beast::http::verb::head)(std::bind_front(
3601 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003602 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003603 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003604 .methods(boost::beast::http::verb::get)(std::bind_front(
3605 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003606}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003607} // namespace redfish