blob: e2e3ed4738e3ec8c134e1df2a14f3bf7ec9d9c3f [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{
Jonathan Doman1e1e5982021-06-11 09:36:17 -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{
Jonathan Doman1e1e5982021-06-11 09:36:17 -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{
126 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
127
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{
Ali Ahmed03fbed92021-09-03 02:33:43 -0500147 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
148
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 {
196 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
197 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 {
215 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
216 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 {
236 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -0700237 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700238 return;
239 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700240 getProcessorProperties(asyncResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200241 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500242}
243
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500244/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500245 * @brief processMemoryProperties fields
246 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700247 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500248 * @param[in] service dbus service for memory Information
249 * @param[in] path dbus path for Memory
250 * @param[in] DBUS properties for memory
251 *
252 * @return None.
253 */
254inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700255 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500256 [[maybe_unused]] const std::string& service,
257 [[maybe_unused]] const std::string& path,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500258 const dbus::utility::DBusPropertiesMap& properties)
259{
260 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Dimm properties.";
261
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 {
275 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
276 return;
277 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700278 updateDimmProperties(asyncResp, dimmState);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500279 });
280 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500281 return;
282 }
283
284 const size_t* memorySizeInKB = nullptr;
285
286 const bool success = sdbusplus::unpackPropertiesNoThrow(
287 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
288 memorySizeInKB);
289
290 if (!success)
291 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700292 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500293 return;
294 }
295
296 if (memorySizeInKB != nullptr)
297 {
298 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700299 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500300 const uint64_t* preValue = totalMemory.get_ptr<const uint64_t*>();
301 if (preValue == nullptr)
302 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700303 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500304 *memorySizeInKB / static_cast<size_t>(1024 * 1024);
305 }
306 else
307 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700308 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500309 *memorySizeInKB / static_cast<size_t>(1024 * 1024) + *preValue;
310 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500311 if constexpr (bmcwebEnableProcMemStatus)
312 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700313 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500314 "Enabled";
315 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500316 }
317}
318
319/*
320 * @brief Get getMemorySummary fields
321 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700322 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500323 * @param[in] service dbus service for memory Information
324 * @param[in] path dbus path for memory
325 *
326 * @return None.
327 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700328inline void
329 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
330 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500331{
332 sdbusplus::asio::getAllProperties(
333 *crow::connections::systemBus, service, path,
334 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700335 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500336 path](const boost::system::error_code& ec2,
337 const dbus::utility::DBusPropertiesMap& properties) {
338 if (ec2)
339 {
340 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -0700341 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500342 return;
343 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700344 processMemoryProperties(asyncResp, service, path, properties);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500345 });
346}
347
348/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700349 * @brief Retrieves computer system properties over dbus
350 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700351 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500352 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700353 *
354 * @return None.
355 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700356inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700357 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700358 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700359{
Ed Tanous6c34de42018-08-29 13:37:36 -0700360 BMCWEB_LOG_DEBUG << "Get available system components.";
George Liue99073f2022-12-09 11:06:16 +0800361 constexpr std::array<std::string_view, 5> interfaces = {
362 "xyz.openbmc_project.Inventory.Decorator.Asset",
363 "xyz.openbmc_project.Inventory.Item.Cpu",
364 "xyz.openbmc_project.Inventory.Item.Dimm",
365 "xyz.openbmc_project.Inventory.Item.System",
366 "xyz.openbmc_project.Common.UUID",
367 };
368 dbus::utility::getSubTree(
369 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700370 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800371 systemHealth](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800372 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700373 if (ec)
374 {
375 BMCWEB_LOG_DEBUG << "DBUS response error";
Ed Tanousac106bf2023-06-07 09:24:59 -0700376 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700377 return;
378 }
379 // Iterate over all retrieved ObjectPaths.
380 for (const std::pair<
381 std::string,
382 std::vector<std::pair<std::string, std::vector<std::string>>>>&
383 object : subtree)
384 {
385 const std::string& path = object.first;
386 BMCWEB_LOG_DEBUG << "Got path: " << path;
387 const std::vector<std::pair<std::string, std::vector<std::string>>>&
388 connectionNames = object.second;
389 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700390 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700391 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700392 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700393
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500394 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
395 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
Ed Tanous002d39b2022-05-31 08:59:27 -0700396
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500397 if constexpr (bmcwebEnableProcMemStatus)
Willy Tu13451e32023-05-24 16:08:18 -0700398 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500399 memoryHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700400 asyncResp, "/MemorySummary/Status"_json_pointer);
Willy Tu13451e32023-05-24 16:08:18 -0700401 systemHealth->children.emplace_back(memoryHealth);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500402
403 if constexpr (bmcwebEnableHealthPopulate)
404 {
405 cpuHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700406 asyncResp, "/ProcessorSummary/Status"_json_pointer);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500407
408 systemHealth->children.emplace_back(cpuHealth);
409 }
Willy Tu13451e32023-05-24 16:08:18 -0700410 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700411
412 // This is not system, so check if it's cpu, dimm, UUID or
413 // BiosVer
414 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700415 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700416 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700417 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700418 if (interfaceName ==
419 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700420 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700421 BMCWEB_LOG_DEBUG
422 << "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 {
434 BMCWEB_LOG_DEBUG
435 << "Found Cpu, now get its properties.";
436
Ed Tanousac106bf2023-06-07 09:24:59 -0700437 getProcessorSummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700438
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500439 if constexpr (bmcwebEnableProcMemStatus)
440 {
441 cpuHealth->inventory.emplace_back(path);
442 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700443 }
444 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
445 {
446 BMCWEB_LOG_DEBUG
447 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200448
449 sdbusplus::asio::getAllProperties(
450 *crow::connections::systemBus, connection.first,
451 path, "xyz.openbmc_project.Common.UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -0700452 [asyncResp](const boost::system::error_code& ec3,
453 const dbus::utility::DBusPropertiesMap&
454 properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700455 if (ec3)
456 {
457 BMCWEB_LOG_DEBUG << "DBUS response error "
458 << ec3;
Ed Tanousac106bf2023-06-07 09:24:59 -0700459 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700460 return;
461 }
462 BMCWEB_LOG_DEBUG << "Got " << properties.size()
463 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700464
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200465 const std::string* uUID = nullptr;
466
467 const bool success =
468 sdbusplus::unpackPropertiesNoThrow(
469 dbus_utils::UnpackErrorPrinter(),
470 properties, "UUID", uUID);
471
472 if (!success)
473 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700474 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200475 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700476 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200477
478 if (uUID != nullptr)
479 {
480 std::string valueStr = *uUID;
481 if (valueStr.size() == 32)
482 {
483 valueStr.insert(8, 1, '-');
484 valueStr.insert(13, 1, '-');
485 valueStr.insert(18, 1, '-');
486 valueStr.insert(23, 1, '-');
487 }
488 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
Ed Tanousac106bf2023-06-07 09:24:59 -0700489 asyncResp->res.jsonValue["UUID"] = valueStr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200490 }
491 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700492 }
493 else if (interfaceName ==
494 "xyz.openbmc_project.Inventory.Item.System")
495 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200496 sdbusplus::asio::getAllProperties(
497 *crow::connections::systemBus, connection.first,
498 path,
499 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700500 [asyncResp](const boost::system::error_code& ec2,
501 const dbus::utility::DBusPropertiesMap&
502 propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700503 if (ec2)
504 {
505 // doesn't have to include this
506 // interface
507 return;
508 }
509 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
510 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200511
512 const std::string* partNumber = nullptr;
513 const std::string* serialNumber = nullptr;
514 const std::string* manufacturer = nullptr;
515 const std::string* model = nullptr;
516 const std::string* subModel = nullptr;
517
518 const bool success =
519 sdbusplus::unpackPropertiesNoThrow(
520 dbus_utils::UnpackErrorPrinter(),
521 propertiesList, "PartNumber", partNumber,
522 "SerialNumber", serialNumber,
523 "Manufacturer", manufacturer, "Model",
524 model, "SubModel", subModel);
525
526 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700527 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700528 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200529 return;
530 }
531
532 if (partNumber != nullptr)
533 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700534 asyncResp->res.jsonValue["PartNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200535 *partNumber;
536 }
537
538 if (serialNumber != nullptr)
539 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700540 asyncResp->res.jsonValue["SerialNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200541 *serialNumber;
542 }
543
544 if (manufacturer != nullptr)
545 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700546 asyncResp->res.jsonValue["Manufacturer"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200547 *manufacturer;
548 }
549
550 if (model != nullptr)
551 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700552 asyncResp->res.jsonValue["Model"] = *model;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200553 }
554
555 if (subModel != nullptr)
556 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700557 asyncResp->res.jsonValue["SubModel"] =
558 *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700559 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500560
Ed Tanous002d39b2022-05-31 08:59:27 -0700561 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700562 sw_util::populateSoftwareInformation(
Ed Tanousac106bf2023-06-07 09:24:59 -0700563 asyncResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700564 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200565 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700566
Ed Tanous002d39b2022-05-31 08:59:27 -0700567 sdbusplus::asio::getProperty<std::string>(
568 *crow::connections::systemBus, connection.first,
569 path,
570 "xyz.openbmc_project.Inventory.Decorator."
571 "AssetTag",
572 "AssetTag",
Ed Tanousac106bf2023-06-07 09:24:59 -0700573 [asyncResp](const boost::system::error_code& ec2,
574 const std::string& value) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700575 if (ec2)
576 {
577 // doesn't have to include this
578 // interface
579 return;
580 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700581
Ed Tanousac106bf2023-06-07 09:24:59 -0700582 asyncResp->res.jsonValue["AssetTag"] = value;
Ed Tanous002d39b2022-05-31 08:59:27 -0700583 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700584 }
585 }
586 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700587 }
Ed Tanous66173382018-08-15 18:20:59 -0700588 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700589}
590
591/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700592 * @brief Retrieves host state properties over dbus
593 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700594 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700595 *
596 * @return None.
597 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700598inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700599{
600 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700601 sdbusplus::asio::getProperty<std::string>(
602 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
603 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
604 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700605 [asyncResp](const boost::system::error_code& ec,
606 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700607 if (ec)
608 {
609 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700610 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700611 // Service not available, no error, just don't return
612 // host state info
613 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700614 return;
615 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700616 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -0700617 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700618 return;
619 }
Ed Tanous66173382018-08-15 18:20:59 -0700620
Ed Tanous002d39b2022-05-31 08:59:27 -0700621 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
622 // Verify Host State
623 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
624 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700625 asyncResp->res.jsonValue["PowerState"] = "On";
626 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700627 }
628 else if (hostState ==
629 "xyz.openbmc_project.State.Host.HostState.Quiesced")
630 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700631 asyncResp->res.jsonValue["PowerState"] = "On";
632 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700633 }
634 else if (hostState ==
635 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
636 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700637 asyncResp->res.jsonValue["PowerState"] = "On";
638 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700639 }
640 else if (
641 hostState ==
642 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
643 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700644 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
645 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700646 }
647 else if (hostState ==
648 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
649 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700650 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
651 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700652 }
653 else
654 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700655 asyncResp->res.jsonValue["PowerState"] = "Off";
656 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700657 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700658 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700659}
660
661/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500662 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530663 *
664 * @param[in] dbusSource The boot source in DBUS speak.
665 *
666 * @return Returns as a string, the boot source in Redfish terms. If translation
667 * cannot be done, returns an empty string.
668 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000669inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530670{
671 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
672 {
673 return "None";
674 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700675 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530676 {
677 return "Hdd";
678 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700679 if (dbusSource ==
680 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530681 {
682 return "Cd";
683 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700684 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530685 {
686 return "Pxe";
687 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700688 if (dbusSource ==
689 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700690 {
691 return "Usb";
692 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700693 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530694}
695
696/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300697 * @brief Translates boot type DBUS property value to redfish.
698 *
699 * @param[in] dbusType The boot type in DBUS speak.
700 *
701 * @return Returns as a string, the boot type in Redfish terms. If translation
702 * cannot be done, returns an empty string.
703 */
704inline std::string dbusToRfBootType(const std::string& dbusType)
705{
706 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
707 {
708 return "Legacy";
709 }
710 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
711 {
712 return "UEFI";
713 }
714 return "";
715}
716
717/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500718 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530719 *
720 * @param[in] dbusMode The boot mode in DBUS speak.
721 *
722 * @return Returns as a string, the boot mode in Redfish terms. If translation
723 * cannot be done, returns an empty string.
724 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000725inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530726{
727 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
728 {
729 return "None";
730 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700731 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530732 {
733 return "Diags";
734 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700735 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530736 {
737 return "BiosSetup";
738 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700739 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530740}
741
742/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600743 * @brief Translates boot progress DBUS property value to redfish.
744 *
745 * @param[in] dbusBootProgress The boot progress in DBUS speak.
746 *
747 * @return Returns as a string, the boot progress in Redfish terms. If
748 * translation cannot be done, returns "None".
749 */
750inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
751{
752 // Now convert the D-Bus BootProgress to the appropriate Redfish
753 // enum
754 std::string rfBpLastState = "None";
755 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
756 "ProgressStages.Unspecified")
757 {
758 rfBpLastState = "None";
759 }
760 else if (dbusBootProgress ==
761 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
762 "PrimaryProcInit")
763 {
764 rfBpLastState = "PrimaryProcessorInitializationStarted";
765 }
766 else if (dbusBootProgress ==
767 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
768 "BusInit")
769 {
770 rfBpLastState = "BusInitializationStarted";
771 }
772 else if (dbusBootProgress ==
773 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
774 "MemoryInit")
775 {
776 rfBpLastState = "MemoryInitializationStarted";
777 }
778 else if (dbusBootProgress ==
779 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
780 "SecondaryProcInit")
781 {
782 rfBpLastState = "SecondaryProcessorInitializationStarted";
783 }
784 else if (dbusBootProgress ==
785 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
786 "PCIInit")
787 {
788 rfBpLastState = "PCIResourceConfigStarted";
789 }
790 else if (dbusBootProgress ==
791 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
792 "SystemSetup")
793 {
794 rfBpLastState = "SetupEntered";
795 }
796 else if (dbusBootProgress ==
797 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
798 "SystemInitComplete")
799 {
800 rfBpLastState = "SystemHardwareInitializationComplete";
801 }
802 else if (dbusBootProgress ==
803 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
804 "OSStart")
805 {
806 rfBpLastState = "OSBootStarted";
807 }
808 else if (dbusBootProgress ==
809 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
810 "OSRunning")
811 {
812 rfBpLastState = "OSRunning";
813 }
814 else
815 {
816 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
817 << dbusBootProgress;
818 // Just return the default
819 }
820 return rfBpLastState;
821}
822
823/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500824 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530825 *
826 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700827 * @param[out] bootSource The DBus source
828 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530829 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700830 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530831 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700832inline int
833 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
834 const std::string& rfSource, std::string& bootSource,
835 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530836{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300837 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
838 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700839
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530840 if (rfSource == "None")
841 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700842 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530843 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700844 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530845 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700846 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
847 }
848 else if (rfSource == "Hdd")
849 {
850 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
851 }
852 else if (rfSource == "Diags")
853 {
854 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
855 }
856 else if (rfSource == "Cd")
857 {
858 bootSource =
859 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
860 }
861 else if (rfSource == "BiosSetup")
862 {
863 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530864 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700865 else if (rfSource == "Usb")
866 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700867 bootSource =
868 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700869 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530870 else
871 {
George Liu0fda0f12021-11-16 10:06:17 +0800872 BMCWEB_LOG_DEBUG
873 << "Invalid property value for BootSourceOverrideTarget: "
874 << bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -0700875 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700876 "BootSourceTargetOverride");
877 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530878 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700879 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530880}
Ali Ahmed19817712021-06-29 17:01:52 -0500881
Andrew Geissler978b8802020-11-19 13:36:40 -0600882/**
883 * @brief Retrieves boot progress of the system
884 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700885 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600886 *
887 * @return None.
888 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700889inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600890{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700891 sdbusplus::asio::getProperty<std::string>(
892 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
893 "/xyz/openbmc_project/state/host0",
894 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700895 [asyncResp](const boost::system::error_code& ec,
896 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700897 if (ec)
898 {
899 // BootProgress is an optional object so just do nothing if
900 // not found
901 return;
902 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600903
Ed Tanous002d39b2022-05-31 08:59:27 -0700904 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600905
Ed Tanousac106bf2023-06-07 09:24:59 -0700906 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700907 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700908 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600909}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530910
911/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000912 * @brief Retrieves boot progress Last Update of the system
913 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700914 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000915 *
916 * @return None.
917 */
918inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700919 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000920{
921 sdbusplus::asio::getProperty<uint64_t>(
922 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
923 "/xyz/openbmc_project/state/host0",
924 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700925 [asyncResp](const boost::system::error_code& ec,
926 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000927 if (ec)
928 {
929 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
930 return;
931 }
932
933 // BootProgressLastUpdate is the last time the BootProgress property
934 // was updated. The time is the Epoch time, number of microseconds
935 // since 1 Jan 1970 00::00::00 UTC."
936 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
937 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
938
939 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700940 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000941 redfish::time_utils::getDateTimeUintUs(lastStateTime);
942 });
943}
944
945/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300946 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300947 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700948 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300949 *
950 * @return None.
951 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300952
Ed Tanousac106bf2023-06-07 09:24:59 -0700953inline void
954 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300955{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700956 sdbusplus::asio::getProperty<std::string>(
957 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
958 "/xyz/openbmc_project/control/host0/boot",
959 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700960 [asyncResp](const boost::system::error_code& ec,
961 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700962 if (ec)
963 {
964 // not an error, don't have to have the interface
965 return;
966 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300967
Ed Tanous002d39b2022-05-31 08:59:27 -0700968 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300969
Ed Tanousac106bf2023-06-07 09:24:59 -0700970 asyncResp->res
971 .jsonValue["Boot"]
972 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700973 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300974
Ed Tanous002d39b2022-05-31 08:59:27 -0700975 auto rfType = dbusToRfBootType(bootType);
976 if (rfType.empty())
977 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700978 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700979 return;
980 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300981
Ed Tanousac106bf2023-06-07 09:24:59 -0700982 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700983 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300984}
985
986/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300987 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530988 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700989 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530990 *
991 * @return None.
992 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300993
Ed Tanousac106bf2023-06-07 09:24:59 -0700994inline void
995 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530996{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700997 sdbusplus::asio::getProperty<std::string>(
998 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
999 "/xyz/openbmc_project/control/host0/boot",
1000 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001001 [asyncResp](const boost::system::error_code& ec,
1002 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001003 if (ec)
1004 {
1005 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001006 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001007 return;
1008 }
1009
1010 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1011
Ed Tanousac106bf2023-06-07 09:24:59 -07001012 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001013 .jsonValue["Boot"]
1014 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1015 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1016
1017 if (bootModeStr !=
1018 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1019 {
1020 auto rfMode = dbusToRfBootMode(bootModeStr);
1021 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301022 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001023 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001024 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301025 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001026 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001027 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301028}
1029
1030/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001031 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301032 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001033 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301034 *
1035 * @return None.
1036 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001037
1038inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001039 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301040{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001041 sdbusplus::asio::getProperty<std::string>(
1042 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1043 "/xyz/openbmc_project/control/host0/boot",
1044 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001045 [asyncResp](const boost::system::error_code& ec,
1046 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001047 if (ec)
1048 {
1049 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001050 if (ec.value() == boost::asio::error::host_unreachable)
1051 {
1052 return;
1053 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001054 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001055 return;
1056 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301057
Ed Tanous002d39b2022-05-31 08:59:27 -07001058 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301059
Ed Tanous002d39b2022-05-31 08:59:27 -07001060 auto rfSource = dbusToRfBootSource(bootSourceStr);
1061 if (!rfSource.empty())
1062 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001063 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1064 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001065 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001066
Ed Tanous002d39b2022-05-31 08:59:27 -07001067 // Get BootMode as BootSourceOverrideTarget is constructed
1068 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001069 getBootOverrideMode(asyncResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001070 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301071}
1072
1073/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001074 * @brief This functions abstracts all the logic behind getting a
1075 * "BootSourceOverrideEnabled" property from an overall boot override enable
1076 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301077 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001078 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301079 *
1080 * @return None.
1081 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301082
Ed Tanousac106bf2023-06-07 09:24:59 -07001083inline void processBootOverrideEnable(
1084 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1085 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001086{
1087 if (!bootOverrideEnableSetting)
1088 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001089 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1090 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001091 return;
1092 }
1093
1094 // If boot source override is enabled, we need to check 'one_time'
1095 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001096 sdbusplus::asio::getProperty<bool>(
1097 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1098 "/xyz/openbmc_project/control/host0/boot/one_time",
1099 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001100 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001101 if (ec)
1102 {
1103 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001104 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001105 return;
1106 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301107
Ed Tanous002d39b2022-05-31 08:59:27 -07001108 if (oneTimeSetting)
1109 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001110 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1111 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001112 }
1113 else
1114 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001115 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001116 "Continuous";
1117 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001118 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301119}
1120
1121/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001122 * @brief Retrieves boot override enable over DBUS
1123 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001124 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001125 *
1126 * @return None.
1127 */
1128
1129inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001130 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001131{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001132 sdbusplus::asio::getProperty<bool>(
1133 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1134 "/xyz/openbmc_project/control/host0/boot",
1135 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001136 [asyncResp](const boost::system::error_code& ec,
1137 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001138 if (ec)
1139 {
1140 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001141 if (ec.value() == boost::asio::error::host_unreachable)
1142 {
1143 return;
1144 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001145 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001146 return;
1147 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001148
Ed Tanousac106bf2023-06-07 09:24:59 -07001149 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001150 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001151}
1152
1153/**
1154 * @brief Retrieves boot source override properties
1155 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001156 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001157 *
1158 * @return None.
1159 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001160inline void
1161 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001162{
1163 BMCWEB_LOG_DEBUG << "Get boot information.";
1164
Ed Tanousac106bf2023-06-07 09:24:59 -07001165 getBootOverrideSource(asyncResp);
1166 getBootOverrideType(asyncResp);
1167 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001168}
1169
1170/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001171 * @brief Retrieves the Last Reset Time
1172 *
1173 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1174 * and power off. Even though this is the "system" Redfish object look at the
1175 * chassis D-Bus interface for the LastStateChangeTime since this has the
1176 * last power operation time.
1177 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001178 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001179 *
1180 * @return None.
1181 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001182inline void
1183 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001184{
1185 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1186
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001187 sdbusplus::asio::getProperty<uint64_t>(
1188 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1189 "/xyz/openbmc_project/state/chassis0",
1190 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001191 [asyncResp](const boost::system::error_code& ec,
1192 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001193 if (ec)
1194 {
1195 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1196 return;
1197 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001198
Ed Tanous002d39b2022-05-31 08:59:27 -07001199 // LastStateChangeTime is epoch time, in milliseconds
1200 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1201 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001202
Ed Tanous002d39b2022-05-31 08:59:27 -07001203 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001204 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001205 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001206 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001207}
1208
1209/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001210 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1211 *
1212 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1213 * corresponding property "AttemptsLeft" that keeps track of the amount of
1214 * automatic retry attempts left are hosted in phosphor-state-manager through
1215 * dbus.
1216 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001217 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001218 *
1219 * @return None.
1220 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001221inline void getAutomaticRebootAttempts(
1222 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001223{
1224 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1225
1226 sdbusplus::asio::getAllProperties(
1227 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1228 "/xyz/openbmc_project/state/host0",
1229 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001230 [asyncResp{asyncResp}](
1231 const boost::system::error_code& ec,
1232 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001233 if (ec)
1234 {
1235 if (ec.value() != EBADR)
1236 {
1237 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001238 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001239 }
1240 return;
1241 }
1242
1243 const uint32_t* attemptsLeft = nullptr;
1244 const uint32_t* retryAttempts = nullptr;
1245
1246 const bool success = sdbusplus::unpackPropertiesNoThrow(
1247 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1248 attemptsLeft, "RetryAttempts", retryAttempts);
1249
1250 if (!success)
1251 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001252 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001253 return;
1254 }
1255
1256 if (attemptsLeft != nullptr)
1257 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001258 asyncResp->res
1259 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001260 *attemptsLeft;
1261 }
1262
1263 if (retryAttempts != nullptr)
1264 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001265 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001266 *retryAttempts;
1267 }
1268 });
1269}
1270
1271/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001272 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1273 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001274 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001275 *
1276 * @return None.
1277 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001278inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001279 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001280{
1281 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1282
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001283 sdbusplus::asio::getProperty<bool>(
1284 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1285 "/xyz/openbmc_project/control/host0/auto_reboot",
1286 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001287 [asyncResp](const boost::system::error_code& ec,
1288 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001289 if (ec)
1290 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001291 if (ec.value() != EBADR)
1292 {
1293 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001294 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001295 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001296 return;
1297 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001298
Ed Tanous002d39b2022-05-31 08:59:27 -07001299 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1300 if (autoRebootEnabled)
1301 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001302 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001303 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001304 }
1305 else
1306 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001307 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1308 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001309 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001310 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001311
Ed Tanous002d39b2022-05-31 08:59:27 -07001312 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1313 // and RetryAttempts. OpenBMC only supports Disabled and
1314 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001315 asyncResp->res
1316 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1317 {"Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001318 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001319}
1320
1321/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001322 * @brief Sets RetryAttempts
1323 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001324 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001325 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1326 *
1327 *@return None.
1328 */
1329
Ed Tanousac106bf2023-06-07 09:24:59 -07001330inline void setAutomaticRetryAttempts(
1331 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1332 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001333{
1334 BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
George Liu9ae226f2023-06-21 17:56:46 +08001335 sdbusplus::asio::setProperty(
1336 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1337 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001338 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001339 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1340 if (ec)
1341 {
1342 BMCWEB_LOG_ERROR
1343 << "DBUS response error: Set setAutomaticRetryAttempts"
1344 << ec;
1345 messages::internalError(asyncResp->res);
1346 return;
1347 }
1348 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001349}
1350
Ed Tanous8d69c662023-06-21 10:29:06 -07001351inline computer_system::PowerRestorePolicyTypes
1352 redfishPowerRestorePolicyFromDbus(std::string_view value)
1353{
1354 if (value ==
1355 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1356 {
1357 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1358 }
1359 if (value ==
1360 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1361 {
1362 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1363 }
1364 if (value ==
1365 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore")
1366 {
1367 return computer_system::PowerRestorePolicyTypes::LastState;
1368 }
1369 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1370 {
1371 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1372 }
1373 return computer_system::PowerRestorePolicyTypes::Invalid;
1374}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001375/**
George Liuc6a620f2020-04-10 17:18:11 +08001376 * @brief Retrieves power restore policy over DBUS.
1377 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001378 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001379 *
1380 * @return None.
1381 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001382inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001383 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001384{
1385 BMCWEB_LOG_DEBUG << "Get power restore policy";
1386
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001387 sdbusplus::asio::getProperty<std::string>(
1388 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1389 "/xyz/openbmc_project/control/host0/power_restore_policy",
1390 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001391 [asyncResp](const boost::system::error_code& ec,
1392 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001393 if (ec)
1394 {
1395 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1396 return;
1397 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001398 computer_system::PowerRestorePolicyTypes restore =
1399 redfishPowerRestorePolicyFromDbus(policy);
1400 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001401 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001402 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001403 return;
1404 }
George Liuc6a620f2020-04-10 17:18:11 +08001405
Ed Tanous8d69c662023-06-21 10:29:06 -07001406 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001407 });
George Liuc6a620f2020-04-10 17:18:11 +08001408}
1409
1410/**
Ali Ahmed19817712021-06-29 17:01:52 -05001411 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1412 * TPM is required for booting the host.
1413 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001414 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001415 *
1416 * @return None.
1417 */
1418inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001419 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001420{
1421 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001422 constexpr std::array<std::string_view, 1> interfaces = {
1423 "xyz.openbmc_project.Control.TPM.Policy"};
1424 dbus::utility::getSubTree(
1425 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001426 [asyncResp](const boost::system::error_code& ec,
1427 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001428 if (ec)
1429 {
1430 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1431 << ec;
1432 // This is an optional D-Bus object so just return if
1433 // error occurs
1434 return;
1435 }
1436 if (subtree.empty())
1437 {
1438 // As noted above, this is an optional interface so just return
1439 // if there is no instance found
1440 return;
1441 }
1442
1443 /* When there is more than one TPMEnable object... */
1444 if (subtree.size() > 1)
1445 {
1446 BMCWEB_LOG_DEBUG
1447 << "DBUS response has more than 1 TPM Enable object:"
1448 << subtree.size();
1449 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001450 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001451 return;
1452 }
1453
1454 // Make sure the Dbus response map has a service and objectPath
1455 // field
1456 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1457 {
1458 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001459 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001460 return;
1461 }
1462
1463 const std::string& path = subtree[0].first;
1464 const std::string& serv = subtree[0].second.begin()->first;
1465
1466 // Valid TPM Enable object found, now reading the current value
1467 sdbusplus::asio::getProperty<bool>(
1468 *crow::connections::systemBus, serv, path,
1469 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001470 [asyncResp](const boost::system::error_code& ec2,
1471 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001472 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001473 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001474 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001475 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001476 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001477 return;
1478 }
1479
Ed Tanous002d39b2022-05-31 08:59:27 -07001480 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001481 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001482 asyncResp->res
1483 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001484 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001485 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001486 else
1487 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001488 asyncResp->res
1489 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001490 "Disabled";
1491 }
1492 });
George Liue99073f2022-12-09 11:06:16 +08001493 });
Ali Ahmed19817712021-06-29 17:01:52 -05001494}
1495
1496/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001497 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1498 * TPM is required for booting the host.
1499 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001500 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001501 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1502 *
1503 * @return None.
1504 */
1505inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001506 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001507{
1508 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001509 constexpr std::array<std::string_view, 1> interfaces = {
1510 "xyz.openbmc_project.Control.TPM.Policy"};
1511 dbus::utility::getSubTree(
1512 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001513 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001514 tpmRequired](const boost::system::error_code& ec,
1515 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001516 if (ec)
1517 {
1518 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1519 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001520 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001521 return;
1522 }
1523 if (subtree.empty())
1524 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001525 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001526 "TrustedModuleRequiredToBoot");
1527 return;
1528 }
1529
1530 /* When there is more than one TPMEnable object... */
1531 if (subtree.size() > 1)
1532 {
1533 BMCWEB_LOG_DEBUG
1534 << "DBUS response has more than 1 TPM Enable object:"
1535 << subtree.size();
1536 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001537 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001538 return;
1539 }
1540
1541 // Make sure the Dbus response map has a service and objectPath
1542 // field
1543 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1544 {
1545 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001546 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001547 return;
1548 }
1549
1550 const std::string& path = subtree[0].first;
1551 const std::string& serv = subtree[0].second.begin()->first;
1552
1553 if (serv.empty())
1554 {
1555 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001556 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001557 return;
1558 }
1559
1560 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001561 sdbusplus::asio::setProperty(
1562 *crow::connections::systemBus, serv, path,
1563 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001564 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001565 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001566 {
1567 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001568 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001569 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001570 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001571 return;
1572 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001573 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
George Liu9ae226f2023-06-21 17:56:46 +08001574 });
George Liue99073f2022-12-09 11:06:16 +08001575 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001576}
1577
1578/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301579 * @brief Sets boot properties into DBUS object(s).
1580 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001581 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001582 * @param[in] bootType The boot type to set.
1583 * @return Integer error code.
1584 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001585inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001586 const std::optional<std::string>& bootType)
1587{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001588 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001589
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001590 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001591 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001592 return;
1593 }
1594
1595 // Source target specified
1596 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1597 // Figure out which DBUS interface and property to use
1598 if (*bootType == "Legacy")
1599 {
1600 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1601 }
1602 else if (*bootType == "UEFI")
1603 {
1604 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1605 }
1606 else
1607 {
1608 BMCWEB_LOG_DEBUG << "Invalid property value for "
1609 "BootSourceOverrideMode: "
1610 << *bootType;
Ed Tanousac106bf2023-06-07 09:24:59 -07001611 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001612 "BootSourceOverrideMode");
1613 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001614 }
1615
1616 // Act on validated parameters
1617 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1618
George Liu9ae226f2023-06-21 17:56:46 +08001619 sdbusplus::asio::setProperty(
1620 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1621 "/xyz/openbmc_project/control/host0/boot",
1622 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001623 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001624 if (ec)
1625 {
1626 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1627 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001628 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001629 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001630 return;
1631 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001632 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001633 return;
1634 }
1635 BMCWEB_LOG_DEBUG << "Boot type update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001636 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001637}
1638
1639/**
1640 * @brief Sets boot properties into DBUS object(s).
1641 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001642 * @param[in] asyncResp Shared pointer for generating response
1643 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001644 * @param[in] bootType The boot type to set.
1645 * @return Integer error code.
1646 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001647inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001648 const std::optional<std::string>& bootEnable)
1649{
1650 if (!bootEnable)
1651 {
1652 return;
1653 }
1654 // Source target specified
1655 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1656
1657 bool bootOverrideEnable = false;
1658 bool bootOverridePersistent = false;
1659 // Figure out which DBUS interface and property to use
1660 if (*bootEnable == "Disabled")
1661 {
1662 bootOverrideEnable = false;
1663 }
1664 else if (*bootEnable == "Once")
1665 {
1666 bootOverrideEnable = true;
1667 bootOverridePersistent = false;
1668 }
1669 else if (*bootEnable == "Continuous")
1670 {
1671 bootOverrideEnable = true;
1672 bootOverridePersistent = true;
1673 }
1674 else
1675 {
George Liu0fda0f12021-11-16 10:06:17 +08001676 BMCWEB_LOG_DEBUG
1677 << "Invalid property value for BootSourceOverrideEnabled: "
1678 << *bootEnable;
Ed Tanousac106bf2023-06-07 09:24:59 -07001679 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001680 "BootSourceOverrideEnabled");
1681 return;
1682 }
1683
1684 // Act on validated parameters
1685 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1686
George Liu9ae226f2023-06-21 17:56:46 +08001687 sdbusplus::asio::setProperty(
1688 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1689 "/xyz/openbmc_project/control/host0/boot",
1690 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001691 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001692 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001693 {
Ed Tanous8a592812022-06-04 09:06:59 -07001694 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001695 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001696 return;
1697 }
1698 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001699 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001700
1701 if (!bootOverrideEnable)
1702 {
1703 return;
1704 }
1705
1706 // In case boot override is enabled we need to set correct value for the
1707 // 'one_time' enable DBus interface
1708 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1709 << bootOverridePersistent;
1710
George Liu9ae226f2023-06-21 17:56:46 +08001711 sdbusplus::asio::setProperty(
1712 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1713 "/xyz/openbmc_project/control/host0/boot/one_time",
1714 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001715 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001716 if (ec)
1717 {
1718 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001719 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001720 return;
1721 }
1722 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001723 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001724}
1725
1726/**
1727 * @brief Sets boot properties into DBUS object(s).
1728 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001729 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301730 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301731 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001732 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301733 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001734inline void
1735 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1736 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301737{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001738 std::string bootSourceStr;
1739 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001740
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001741 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301742 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001743 return;
1744 }
1745
1746 // Source target specified
1747 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1748 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001749 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1750 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001751 {
1752 BMCWEB_LOG_DEBUG
1753 << "Invalid property value for BootSourceOverrideTarget: "
1754 << *bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -07001755 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001756 "BootSourceTargetOverride");
1757 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001758 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301759
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001760 // Act on validated parameters
1761 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1762 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001763
George Liu9ae226f2023-06-21 17:56:46 +08001764 sdbusplus::asio::setProperty(
1765 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1766 "/xyz/openbmc_project/control/host0/boot",
1767 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001768 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001769 if (ec)
1770 {
1771 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001772 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001773 return;
1774 }
1775 BMCWEB_LOG_DEBUG << "Boot source update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001776 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001777
George Liu9ae226f2023-06-21 17:56:46 +08001778 sdbusplus::asio::setProperty(
1779 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1780 "/xyz/openbmc_project/control/host0/boot",
1781 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001782 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001783 if (ec)
1784 {
1785 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001786 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001787 return;
1788 }
1789 BMCWEB_LOG_DEBUG << "Boot mode update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001790 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001791}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001792
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001793/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001794 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301795 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001796 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301797 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001798 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301799 * @param[in] bootEnable The boot override enable from incoming RF request.
1800 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001801 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301802 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001803
Ed Tanousac106bf2023-06-07 09:24:59 -07001804inline void
1805 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1806 const std::optional<std::string>& bootSource,
1807 const std::optional<std::string>& bootType,
1808 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301809{
1810 BMCWEB_LOG_DEBUG << "Set boot information.";
1811
Ed Tanousac106bf2023-06-07 09:24:59 -07001812 setBootModeOrSource(asyncResp, bootSource);
1813 setBootType(asyncResp, bootType);
1814 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301815}
1816
George Liuc6a620f2020-04-10 17:18:11 +08001817/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001818 * @brief Sets AssetTag
1819 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001820 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001821 * @param[in] assetTag "AssetTag" from request.
1822 *
1823 * @return None.
1824 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001825inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001826 const std::string& assetTag)
1827{
George Liue99073f2022-12-09 11:06:16 +08001828 constexpr std::array<std::string_view, 1> interfaces = {
1829 "xyz.openbmc_project.Inventory.Item.System"};
1830 dbus::utility::getSubTree(
1831 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001832 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001833 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001834 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001835 if (ec)
1836 {
1837 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001838 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001839 return;
1840 }
1841 if (subtree.empty())
1842 {
1843 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001844 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001845 return;
1846 }
1847 // Assume only 1 system D-Bus object
1848 // Throw an error if there is more than 1
1849 if (subtree.size() > 1)
1850 {
1851 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001852 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001853 return;
1854 }
1855 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1856 {
1857 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001858 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001859 return;
1860 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001861
Ed Tanous002d39b2022-05-31 08:59:27 -07001862 const std::string& path = subtree[0].first;
1863 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001864
Ed Tanous002d39b2022-05-31 08:59:27 -07001865 if (service.empty())
1866 {
1867 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001868 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001869 return;
1870 }
1871
George Liu9ae226f2023-06-21 17:56:46 +08001872 sdbusplus::asio::setProperty(
1873 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001874 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001875 assetTag, [asyncResp](const boost::system::error_code& ec2) {
1876 if (ec2)
1877 {
1878 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1879 << ec2;
1880 messages::internalError(asyncResp->res);
1881 return;
1882 }
1883 });
George Liue99073f2022-12-09 11:06:16 +08001884 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001885}
1886
1887/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001888 * @brief Sets automaticRetry (Auto Reboot)
1889 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001890 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001891 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1892 *
1893 * @return None.
1894 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001895inline void
1896 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1897 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001898{
1899 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1900
1901 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001902 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001903
1904 if (automaticRetryConfig == "Disabled")
1905 {
1906 autoRebootEnabled = false;
1907 }
1908 else if (automaticRetryConfig == "RetryAttempts")
1909 {
1910 autoRebootEnabled = true;
1911 }
1912 else
1913 {
George Liu0fda0f12021-11-16 10:06:17 +08001914 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001915 << automaticRetryConfig;
Ed Tanousac106bf2023-06-07 09:24:59 -07001916 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001917 "AutomaticRetryConfig");
1918 return;
1919 }
1920
George Liu9ae226f2023-06-21 17:56:46 +08001921 sdbusplus::asio::setProperty(
1922 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05001923 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05001924 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08001925 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
1926 if (ec)
1927 {
1928 messages::internalError(asyncResp->res);
1929 return;
1930 }
1931 });
Gunnar Mills69f35302020-05-17 16:06:31 -05001932}
1933
Ed Tanous8d69c662023-06-21 10:29:06 -07001934inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1935{
1936 if (policy == "AlwaysOn")
1937 {
1938 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1939 }
1940 if (policy == "AlwaysOff")
1941 {
1942 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1943 }
1944 if (policy == "LastState")
1945 {
1946 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1947 }
1948 return "";
1949}
1950
Gunnar Mills69f35302020-05-17 16:06:31 -05001951/**
George Liuc6a620f2020-04-10 17:18:11 +08001952 * @brief Sets power restore policy properties.
1953 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001954 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001955 * @param[in] policy power restore policy properties from request.
1956 *
1957 * @return None.
1958 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001959inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001960 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001961 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08001962{
1963 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1964
Ed Tanous8d69c662023-06-21 10:29:06 -07001965 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001966
Ed Tanous8d69c662023-06-21 10:29:06 -07001967 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08001968 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001969 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06001970 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001971 return;
1972 }
1973
George Liu9ae226f2023-06-21 17:56:46 +08001974 sdbusplus::asio::setProperty(
1975 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08001976 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08001977 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08001978 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
1979 if (ec)
1980 {
1981 messages::internalError(asyncResp->res);
1982 return;
1983 }
1984 });
George Liuc6a620f2020-04-10 17:18:11 +08001985}
1986
AppaRao Pulia6349912019-10-18 17:16:08 +05301987#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1988/**
1989 * @brief Retrieves provisioning status
1990 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001991 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05301992 *
1993 * @return None.
1994 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001995inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301996{
1997 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001998 sdbusplus::asio::getAllProperties(
1999 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2000 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002001 [asyncResp](const boost::system::error_code& ec,
2002 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002003 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002004 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2005 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002006 "#OemComputerSystem.OpenBmc";
2007 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002008
Ed Tanous002d39b2022-05-31 08:59:27 -07002009 if (ec)
2010 {
2011 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2012 // not an error, don't have to have the interface
2013 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2014 return;
2015 }
2016
2017 const bool* provState = nullptr;
2018 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002019
2020 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002021 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2022 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002023
2024 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002025 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002026 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002027 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002028 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302029
Ed Tanous002d39b2022-05-31 08:59:27 -07002030 if ((provState == nullptr) || (lockState == nullptr))
2031 {
2032 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
Ed Tanousac106bf2023-06-07 09:24:59 -07002033 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002034 return;
2035 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302036
Ed Tanous002d39b2022-05-31 08:59:27 -07002037 if (*provState == true)
2038 {
2039 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302040 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002041 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302042 }
2043 else
2044 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002045 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302046 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002047 }
2048 else
2049 {
2050 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2051 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002052 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302053}
2054#endif
2055
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302056/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002057 * @brief Translate the PowerMode to a response message.
2058 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002059 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002060 * @param[in] modeValue PowerMode value to be translated
2061 *
2062 * @return None.
2063 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002064inline void
2065 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2066 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002067{
George Liu0fda0f12021-11-16 10:06:17 +08002068 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002069 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002070 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002071 }
George Liu0fda0f12021-11-16 10:06:17 +08002072 else if (
2073 modeValue ==
2074 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002075 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002076 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002077 }
George Liu0fda0f12021-11-16 10:06:17 +08002078 else if (modeValue ==
2079 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002080 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002081 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002082 }
George Liu0fda0f12021-11-16 10:06:17 +08002083 else if (modeValue ==
2084 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002085 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002086 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002087 }
2088 else
2089 {
2090 // Any other values would be invalid
2091 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
Ed Tanousac106bf2023-06-07 09:24:59 -07002092 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002093 }
2094}
2095
2096/**
2097 * @brief Retrieves system power mode
2098 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002099 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002100 *
2101 * @return None.
2102 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002103inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002104{
2105 BMCWEB_LOG_DEBUG << "Get power mode.";
2106
2107 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002108 constexpr std::array<std::string_view, 1> interfaces = {
2109 "xyz.openbmc_project.Control.Power.Mode"};
2110 dbus::utility::getSubTree(
2111 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002112 [asyncResp](const boost::system::error_code& ec,
2113 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002114 if (ec)
2115 {
2116 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2117 << ec;
2118 // This is an optional D-Bus object so just return if
2119 // error occurs
2120 return;
2121 }
2122 if (subtree.empty())
2123 {
2124 // As noted above, this is an optional interface so just return
2125 // if there is no instance found
2126 return;
2127 }
2128 if (subtree.size() > 1)
2129 {
2130 // More then one PowerMode object is not supported and is an
2131 // error
2132 BMCWEB_LOG_DEBUG
2133 << "Found more than 1 system D-Bus Power.Mode objects: "
2134 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002135 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002136 return;
2137 }
2138 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2139 {
2140 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002141 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002142 return;
2143 }
2144 const std::string& path = subtree[0].first;
2145 const std::string& service = subtree[0].second.begin()->first;
2146 if (service.empty())
2147 {
2148 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002149 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002150 return;
2151 }
2152 // Valid Power Mode object found, now read the current value
2153 sdbusplus::asio::getProperty<std::string>(
2154 *crow::connections::systemBus, service, path,
2155 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002156 [asyncResp](const boost::system::error_code& ec2,
2157 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002158 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002159 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002160 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002161 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002162 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002163 return;
2164 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002165
Ed Tanousac106bf2023-06-07 09:24:59 -07002166 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002167 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002168
Ed Tanous002d39b2022-05-31 08:59:27 -07002169 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
Ed Tanousac106bf2023-06-07 09:24:59 -07002170 translatePowerMode(asyncResp, pmode);
Ed Tanous002d39b2022-05-31 08:59:27 -07002171 });
George Liue99073f2022-12-09 11:06:16 +08002172 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002173}
2174
2175/**
2176 * @brief Validate the specified mode is valid and return the PowerMode
2177 * name associated with that string
2178 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002179 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002180 * @param[in] modeString String representing the desired PowerMode
2181 *
2182 * @return PowerMode value or empty string if mode is not valid
2183 */
2184inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002185 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002186 const std::string& modeString)
2187{
2188 std::string mode;
2189
2190 if (modeString == "Static")
2191 {
2192 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2193 }
2194 else if (modeString == "MaximumPerformance")
2195 {
George Liu0fda0f12021-11-16 10:06:17 +08002196 mode =
2197 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002198 }
2199 else if (modeString == "PowerSaving")
2200 {
2201 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2202 }
2203 else
2204 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002205 messages::propertyValueNotInList(asyncResp->res, modeString,
2206 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002207 }
2208 return mode;
2209}
2210
2211/**
2212 * @brief Sets system power mode.
2213 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002214 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002215 * @param[in] pmode System power mode from request.
2216 *
2217 * @return None.
2218 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002219inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002220 const std::string& pmode)
2221{
2222 BMCWEB_LOG_DEBUG << "Set power mode.";
2223
Ed Tanousac106bf2023-06-07 09:24:59 -07002224 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002225 if (powerMode.empty())
2226 {
2227 return;
2228 }
2229
2230 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002231 constexpr std::array<std::string_view, 1> interfaces = {
2232 "xyz.openbmc_project.Control.Power.Mode"};
2233 dbus::utility::getSubTree(
2234 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002235 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002236 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002237 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002238 if (ec)
2239 {
2240 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2241 << ec;
2242 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002243 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002244 return;
2245 }
2246 if (subtree.empty())
2247 {
2248 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002249 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002250 "PowerMode");
2251 return;
2252 }
2253 if (subtree.size() > 1)
2254 {
2255 // More then one PowerMode object is not supported and is an
2256 // error
2257 BMCWEB_LOG_DEBUG
2258 << "Found more than 1 system D-Bus Power.Mode objects: "
2259 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002260 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002261 return;
2262 }
2263 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2264 {
2265 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002266 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002267 return;
2268 }
2269 const std::string& path = subtree[0].first;
2270 const std::string& service = subtree[0].second.begin()->first;
2271 if (service.empty())
2272 {
2273 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002274 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002275 return;
2276 }
2277
2278 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2279 << path;
2280
2281 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002282 sdbusplus::asio::setProperty(
2283 *crow::connections::systemBus, service, path,
2284 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002285 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002286 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002287 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002288 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002289 return;
2290 }
George Liu9ae226f2023-06-21 17:56:46 +08002291 });
George Liue99073f2022-12-09 11:06:16 +08002292 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002293}
2294
2295/**
Yong Li51709ff2019-09-30 14:13:04 +08002296 * @brief Translates watchdog timeout action DBUS property value to redfish.
2297 *
2298 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2299 *
2300 * @return Returns as a string, the timeout action in Redfish terms. If
2301 * translation cannot be done, returns an empty string.
2302 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002303inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002304{
2305 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2306 {
2307 return "None";
2308 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002309 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002310 {
2311 return "ResetSystem";
2312 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002313 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002314 {
2315 return "PowerDown";
2316 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002317 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002318 {
2319 return "PowerCycle";
2320 }
2321
2322 return "";
2323}
2324
2325/**
Yong Lic45f0082019-10-10 14:19:01 +08002326 *@brief Translates timeout action from Redfish to DBUS property value.
2327 *
2328 *@param[in] rfAction The timeout action in Redfish.
2329 *
2330 *@return Returns as a string, the time_out action as expected by DBUS.
2331 *If translation cannot be done, returns an empty string.
2332 */
2333
Ed Tanous23a21a12020-07-25 04:45:05 +00002334inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002335{
2336 if (rfAction == "None")
2337 {
2338 return "xyz.openbmc_project.State.Watchdog.Action.None";
2339 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002340 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002341 {
2342 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2343 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002344 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002345 {
2346 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2347 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002348 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002349 {
2350 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2351 }
2352
2353 return "";
2354}
2355
2356/**
Yong Li51709ff2019-09-30 14:13:04 +08002357 * @brief Retrieves host watchdog timer properties over DBUS
2358 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002359 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002360 *
2361 * @return None.
2362 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002363inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002364 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002365{
2366 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002367 sdbusplus::asio::getAllProperties(
2368 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2369 "/xyz/openbmc_project/watchdog/host0",
2370 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002371 [asyncResp](const boost::system::error_code& ec,
2372 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002373 if (ec)
2374 {
2375 // watchdog service is stopped
2376 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2377 return;
2378 }
2379
2380 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2381
2382 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002383 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002384
2385 // watchdog service is running/enabled
2386 hostWatchdogTimer["Status"]["State"] = "Enabled";
2387
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002388 const bool* enabled = nullptr;
2389 const std::string* expireAction = nullptr;
2390
2391 const bool success = sdbusplus::unpackPropertiesNoThrow(
2392 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2393 "ExpireAction", expireAction);
2394
2395 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002396 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002397 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002398 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002399 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002400
2401 if (enabled != nullptr)
2402 {
2403 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2404 }
2405
2406 if (expireAction != nullptr)
2407 {
2408 std::string action = dbusToRfWatchdogAction(*expireAction);
2409 if (action.empty())
2410 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002411 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002412 return;
2413 }
2414 hostWatchdogTimer["TimeoutAction"] = action;
2415 }
2416 });
Yong Li51709ff2019-09-30 14:13:04 +08002417}
2418
2419/**
Yong Lic45f0082019-10-10 14:19:01 +08002420 * @brief Sets Host WatchDog Timer properties.
2421 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002422 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002423 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2424 * RF request.
2425 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2426 *
2427 * @return None.
2428 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002429inline void
2430 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2431 const std::optional<bool> wdtEnable,
2432 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002433{
2434 BMCWEB_LOG_DEBUG << "Set host watchdog";
2435
2436 if (wdtTimeOutAction)
2437 {
2438 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2439 // check if TimeOut Action is Valid
2440 if (wdtTimeOutActStr.empty())
2441 {
2442 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2443 << *wdtTimeOutAction;
Ed Tanousac106bf2023-06-07 09:24:59 -07002444 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002445 "TimeoutAction");
2446 return;
2447 }
2448
George Liu9ae226f2023-06-21 17:56:46 +08002449 sdbusplus::asio::setProperty(
2450 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002451 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002452 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002453 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2454 if (ec)
2455 {
2456 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2457 messages::internalError(asyncResp->res);
2458 return;
2459 }
2460 });
Yong Lic45f0082019-10-10 14:19:01 +08002461 }
2462
2463 if (wdtEnable)
2464 {
George Liu9ae226f2023-06-21 17:56:46 +08002465 sdbusplus::asio::setProperty(
2466 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2467 "/xyz/openbmc_project/watchdog/host0",
2468 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002469 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002470 if (ec)
2471 {
2472 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002473 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002474 return;
2475 }
George Liu9ae226f2023-06-21 17:56:46 +08002476 });
Yong Lic45f0082019-10-10 14:19:01 +08002477 }
2478}
2479
Chris Cain37bbf982021-09-20 10:53:09 -05002480/**
2481 * @brief Parse the Idle Power Saver properties into json
2482 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002483 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002484 * @param[in] properties IPS property data from DBus.
2485 *
2486 * @return true if successful
2487 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002488inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002489 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002490 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002491{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002492 const bool* enabled = nullptr;
2493 const uint8_t* enterUtilizationPercent = nullptr;
2494 const uint64_t* enterDwellTime = nullptr;
2495 const uint8_t* exitUtilizationPercent = nullptr;
2496 const uint64_t* exitDwellTime = nullptr;
2497
2498 const bool success = sdbusplus::unpackPropertiesNoThrow(
2499 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002500 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2501 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2502 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002503
2504 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002505 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002506 return false;
2507 }
2508
2509 if (enabled != nullptr)
2510 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002511 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002512 }
2513
2514 if (enterUtilizationPercent != nullptr)
2515 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002516 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002517 *enterUtilizationPercent;
2518 }
2519
2520 if (enterDwellTime != nullptr)
2521 {
2522 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002523 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002524 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2525 .count();
2526 }
2527
2528 if (exitUtilizationPercent != nullptr)
2529 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002530 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002531 *exitUtilizationPercent;
2532 }
2533
2534 if (exitDwellTime != nullptr)
2535 {
2536 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002537 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002538 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2539 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002540 }
2541
2542 return true;
2543}
2544
2545/**
2546 * @brief Retrieves host watchdog timer properties over DBUS
2547 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002548 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002549 *
2550 * @return None.
2551 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002552inline void
2553 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002554{
2555 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2556
2557 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002558 constexpr std::array<std::string_view, 1> interfaces = {
2559 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2560 dbus::utility::getSubTree(
2561 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002562 [asyncResp](const boost::system::error_code& ec,
2563 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002564 if (ec)
2565 {
2566 BMCWEB_LOG_DEBUG
2567 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2568 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002569 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002570 return;
2571 }
2572 if (subtree.empty())
2573 {
2574 // This is an optional interface so just return
2575 // if there is no instance found
2576 BMCWEB_LOG_DEBUG << "No instances found";
2577 return;
2578 }
2579 if (subtree.size() > 1)
2580 {
2581 // More then one PowerIdlePowerSaver object is not supported and
2582 // is an error
2583 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2584 "Power.IdlePowerSaver objects: "
2585 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002586 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002587 return;
2588 }
2589 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2590 {
2591 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002592 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002593 return;
2594 }
2595 const std::string& path = subtree[0].first;
2596 const std::string& service = subtree[0].second.begin()->first;
2597 if (service.empty())
2598 {
2599 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002600 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002601 return;
2602 }
2603
2604 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002605 sdbusplus::asio::getAllProperties(
2606 *crow::connections::systemBus, service, path,
2607 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002608 [asyncResp](const boost::system::error_code& ec2,
2609 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002610 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002611 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002612 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002613 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002614 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002615 return;
2616 }
2617
Ed Tanousac106bf2023-06-07 09:24:59 -07002618 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002619 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002620 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002621 return;
2622 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002623 });
George Liue99073f2022-12-09 11:06:16 +08002624 });
Chris Cain37bbf982021-09-20 10:53:09 -05002625
2626 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2627}
2628
2629/**
2630 * @brief Sets Idle Power Saver properties.
2631 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002632 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002633 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2634 * RF request.
2635 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2636 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2637 * before entering idle state.
2638 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2639 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2640 * before exiting idle state
2641 *
2642 * @return None.
2643 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002644inline void
2645 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2646 const std::optional<bool> ipsEnable,
2647 const std::optional<uint8_t> ipsEnterUtil,
2648 const std::optional<uint64_t> ipsEnterTime,
2649 const std::optional<uint8_t> ipsExitUtil,
2650 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002651{
2652 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2653
2654 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002655 constexpr std::array<std::string_view, 1> interfaces = {
2656 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2657 dbus::utility::getSubTree(
2658 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002659 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002660 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002661 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002662 if (ec)
2663 {
2664 BMCWEB_LOG_DEBUG
2665 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2666 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002667 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002668 return;
2669 }
2670 if (subtree.empty())
2671 {
2672 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002673 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002674 "IdlePowerSaver");
2675 return;
2676 }
2677 if (subtree.size() > 1)
2678 {
2679 // More then one PowerIdlePowerSaver object is not supported and
2680 // is an error
2681 BMCWEB_LOG_DEBUG
2682 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2683 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002684 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002685 return;
2686 }
2687 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2688 {
2689 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002690 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002691 return;
2692 }
2693 const std::string& path = subtree[0].first;
2694 const std::string& service = subtree[0].second.begin()->first;
2695 if (service.empty())
2696 {
2697 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002698 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002699 return;
2700 }
Chris Cain37bbf982021-09-20 10:53:09 -05002701
Ed Tanous002d39b2022-05-31 08:59:27 -07002702 // Valid Power IdlePowerSaver object found, now set any values that
2703 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002704
Ed Tanous002d39b2022-05-31 08:59:27 -07002705 if (ipsEnable)
2706 {
George Liu9ae226f2023-06-21 17:56:46 +08002707 sdbusplus::asio::setProperty(
2708 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002709 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002710 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
2711 if (ec2)
2712 {
2713 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2714 messages::internalError(asyncResp->res);
2715 return;
2716 }
2717 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002718 }
2719 if (ipsEnterUtil)
2720 {
George Liu9ae226f2023-06-21 17:56:46 +08002721 sdbusplus::asio::setProperty(
2722 *crow::connections::systemBus, service, path,
2723 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2724 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002725 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002726 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002727 {
Ed Tanous8a592812022-06-04 09:06:59 -07002728 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002729 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002730 return;
2731 }
George Liu9ae226f2023-06-21 17:56:46 +08002732 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002733 }
2734 if (ipsEnterTime)
2735 {
2736 // Convert from seconds into milliseconds for DBus
2737 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002738 sdbusplus::asio::setProperty(
2739 *crow::connections::systemBus, service, path,
2740 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2741 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002742 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002743 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002744 {
Ed Tanous8a592812022-06-04 09:06:59 -07002745 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002746 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002747 return;
2748 }
George Liu9ae226f2023-06-21 17:56:46 +08002749 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002750 }
2751 if (ipsExitUtil)
2752 {
George Liu9ae226f2023-06-21 17:56:46 +08002753 sdbusplus::asio::setProperty(
2754 *crow::connections::systemBus, service, path,
2755 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2756 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002757 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002758 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002759 {
Ed Tanous8a592812022-06-04 09:06:59 -07002760 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002761 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002762 return;
2763 }
George Liu9ae226f2023-06-21 17:56:46 +08002764 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002765 }
2766 if (ipsExitTime)
2767 {
2768 // Convert from seconds into milliseconds for DBus
2769 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002770 sdbusplus::asio::setProperty(
2771 *crow::connections::systemBus, service, path,
2772 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2773 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002774 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002775 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002776 {
Ed Tanous8a592812022-06-04 09:06:59 -07002777 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002778 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002779 return;
2780 }
George Liu9ae226f2023-06-21 17:56:46 +08002781 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002782 }
George Liue99073f2022-12-09 11:06:16 +08002783 });
Chris Cain37bbf982021-09-20 10:53:09 -05002784
2785 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2786}
2787
Ed Tanousc1e219d2023-06-07 10:34:33 -07002788inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002789 crow::App& app, const crow::Request& req,
2790 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2791{
2792 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2793 {
2794 return;
2795 }
2796 asyncResp->res.addHeader(
2797 boost::beast::http::field::link,
2798 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2799}
2800
Ed Tanousc1e219d2023-06-07 10:34:33 -07002801inline void handleComputerSystemCollectionGet(
2802 crow::App& app, const crow::Request& req,
2803 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2804{
2805 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2806 {
2807 return;
2808 }
2809
2810 asyncResp->res.addHeader(
2811 boost::beast::http::field::link,
2812 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2813 asyncResp->res.jsonValue["@odata.type"] =
2814 "#ComputerSystemCollection.ComputerSystemCollection";
2815 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2816 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2817
2818 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2819 ifaceArray = nlohmann::json::array();
2820 if constexpr (bmcwebEnableMultiHost)
2821 {
2822 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2823 // Option currently returns no systems. TBD
2824 return;
2825 }
2826 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2827 nlohmann::json::object_t system;
2828 system["@odata.id"] = "/redfish/v1/Systems/system";
2829 ifaceArray.emplace_back(std::move(system));
2830 sdbusplus::asio::getProperty<std::string>(
2831 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2832 "/xyz/openbmc_project/network/hypervisor",
2833 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2834 [asyncResp](const boost::system::error_code& ec2,
2835 const std::string& /*hostName*/) {
2836 if (ec2)
2837 {
2838 return;
2839 }
2840 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2841 if (val == asyncResp->res.jsonValue.end())
2842 {
2843 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2844 return;
2845 }
2846 uint64_t* count = val->get_ptr<uint64_t*>();
2847 if (count == nullptr)
2848 {
2849 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2850 return;
2851 }
2852 *count = *count + 1;
2853 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2854 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2855 nlohmann::json::object_t hypervisor;
2856 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2857 ifaceArray2.emplace_back(std::move(hypervisor));
2858 });
2859}
2860
Yong Lic45f0082019-10-10 14:19:01 +08002861/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002862 * Function transceives data with dbus directly.
2863 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002864inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002865{
Patrick Williams89492a12023-05-10 07:51:34 -05002866 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2867 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2868 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002869 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002870 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002871
2872 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002873 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002874 if (ec)
2875 {
2876 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2877 messages::internalError(asyncResp->res);
2878 return;
2879 }
2880 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002881 },
2882 serviceName, objectPath, interfaceName, method);
2883}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002884
2885/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002886 * Handle error responses from d-bus for system power requests
2887 */
2888inline void handleSystemActionResetError(const boost::system::error_code& ec,
2889 const sdbusplus::message_t& eMsg,
2890 std::string_view resetType,
2891 crow::Response& res)
2892{
2893 if (ec.value() == boost::asio::error::invalid_argument)
2894 {
2895 messages::actionParameterNotSupported(res, resetType, "Reset");
2896 return;
2897 }
2898
2899 if (eMsg.get_error() == nullptr)
2900 {
2901 BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
2902 messages::internalError(res);
2903 return;
2904 }
2905 std::string_view errorMessage = eMsg.get_error()->name;
2906
2907 // If operation failed due to BMC not being in Ready state, tell
2908 // user to retry in a bit
2909 if ((errorMessage ==
2910 std::string_view(
2911 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
2912 (errorMessage ==
2913 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
2914 {
2915 BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
2916 messages::serviceTemporarilyUnavailable(res, "10");
2917 return;
2918 }
2919
2920 BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
2921 << " sdbusplus:" << errorMessage;
2922 messages::internalError(res);
2923}
2924
Ed Tanousc1e219d2023-06-07 10:34:33 -07002925inline void handleComputerSystemResetActionPost(
2926 crow::App& app, const crow::Request& req,
2927 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2928 const std::string& systemName)
2929{
2930 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2931 {
2932 return;
2933 }
2934 if (systemName != "system")
2935 {
2936 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2937 systemName);
2938 return;
2939 }
2940 if constexpr (bmcwebEnableMultiHost)
2941 {
2942 // Option currently returns no systems. TBD
2943 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2944 systemName);
2945 return;
2946 }
2947 std::string resetType;
2948 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2949 {
2950 return;
2951 }
2952
2953 // Get the command and host vs. chassis
2954 std::string command;
2955 bool hostCommand = true;
2956 if ((resetType == "On") || (resetType == "ForceOn"))
2957 {
2958 command = "xyz.openbmc_project.State.Host.Transition.On";
2959 hostCommand = true;
2960 }
2961 else if (resetType == "ForceOff")
2962 {
2963 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2964 hostCommand = false;
2965 }
2966 else if (resetType == "ForceRestart")
2967 {
2968 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2969 hostCommand = true;
2970 }
2971 else if (resetType == "GracefulShutdown")
2972 {
2973 command = "xyz.openbmc_project.State.Host.Transition.Off";
2974 hostCommand = true;
2975 }
2976 else if (resetType == "GracefulRestart")
2977 {
2978 command =
2979 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2980 hostCommand = true;
2981 }
2982 else if (resetType == "PowerCycle")
2983 {
2984 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2985 hostCommand = true;
2986 }
2987 else if (resetType == "Nmi")
2988 {
2989 doNMI(asyncResp);
2990 return;
2991 }
2992 else
2993 {
2994 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2995 return;
2996 }
2997
2998 if (hostCommand)
2999 {
George Liu9ae226f2023-06-21 17:56:46 +08003000 sdbusplus::asio::setProperty(
3001 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3002 "/xyz/openbmc_project/state/host0",
3003 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3004 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003005 [asyncResp, resetType](const boost::system::error_code& ec,
3006 sdbusplus::message_t& sdbusErrMsg) {
3007 if (ec)
3008 {
3009 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3010 asyncResp->res);
3011
3012 return;
3013 }
3014 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003015 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003016 }
3017 else
3018 {
George Liu9ae226f2023-06-21 17:56:46 +08003019 sdbusplus::asio::setProperty(
3020 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3021 "/xyz/openbmc_project/state/chassis0",
3022 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3023 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003024 [asyncResp, resetType](const boost::system::error_code& ec,
3025 sdbusplus::message_t& sdbusErrMsg) {
3026 if (ec)
3027 {
3028 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3029 asyncResp->res);
3030 return;
3031 }
3032 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003033 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003034 }
3035}
3036
Ed Tanousc1e219d2023-06-07 10:34:33 -07003037inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003038 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003039 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3040 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003041{
3042 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3043 {
3044 return;
3045 }
3046
3047 asyncResp->res.addHeader(
3048 boost::beast::http::field::link,
3049 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3050}
3051
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003052inline void afterPortRequest(
3053 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3054 const boost::system::error_code& ec,
3055 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3056{
3057 if (ec)
3058 {
3059 messages::internalError(asyncResp->res);
3060 return;
3061 }
3062 for (const auto& data : socketData)
3063 {
3064 const std::string& socketPath = get<0>(data);
3065 const std::string& protocolName = get<1>(data);
3066 bool isProtocolEnabled = get<2>(data);
3067 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3068 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3069 // need to retrieve port number for
3070 // obmc-console-ssh service
3071 if (protocolName == "SSH")
3072 {
3073 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003074 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003075 int portNumber) {
3076 if (ec1)
3077 {
3078 messages::internalError(asyncResp->res);
3079 return;
3080 }
3081 nlohmann::json& dataJson1 =
3082 asyncResp->res.jsonValue["SerialConsole"];
3083 dataJson1[protocolName]["Port"] = portNumber;
3084 });
3085 }
3086 }
3087}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003088
3089inline void
3090 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3091 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3092 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003093{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003094 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3095 {
3096 return;
3097 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003098
Ed Tanousc1e219d2023-06-07 10:34:33 -07003099 if constexpr (bmcwebEnableMultiHost)
3100 {
3101 // Option currently returns no systems. TBD
3102 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3103 systemName);
3104 return;
3105 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003106
Ed Tanousc1e219d2023-06-07 10:34:33 -07003107 if (systemName == "hypervisor")
3108 {
3109 handleHypervisorSystemGet(asyncResp);
3110 return;
3111 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003112
Ed Tanousc1e219d2023-06-07 10:34:33 -07003113 if (systemName != "system")
3114 {
3115 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3116 systemName);
3117 return;
3118 }
3119 asyncResp->res.addHeader(
3120 boost::beast::http::field::link,
3121 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3122 asyncResp->res.jsonValue["@odata.type"] =
3123 "#ComputerSystem.v1_16_0.ComputerSystem";
3124 asyncResp->res.jsonValue["Name"] = "system";
3125 asyncResp->res.jsonValue["Id"] = "system";
3126 asyncResp->res.jsonValue["SystemType"] = "Physical";
3127 asyncResp->res.jsonValue["Description"] = "Computer System";
3128 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3129 if constexpr (bmcwebEnableProcMemStatus)
3130 {
3131 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3132 "Disabled";
3133 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3134 "Disabled";
3135 }
3136 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3137 uint64_t(0);
3138 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003139
Ed Tanousc1e219d2023-06-07 10:34:33 -07003140 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3141 "/redfish/v1/Systems/system/Processors";
3142 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3143 "/redfish/v1/Systems/system/Memory";
3144 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3145 "/redfish/v1/Systems/system/Storage";
3146 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3147 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003148
Ed Tanousc1e219d2023-06-07 10:34:33 -07003149 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3150 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3151 asyncResp->res
3152 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3153 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003154
Ed Tanousc1e219d2023-06-07 10:34:33 -07003155 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3156 "/redfish/v1/Systems/system/LogServices";
3157 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3158 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003159
Ed Tanousc1e219d2023-06-07 10:34:33 -07003160 nlohmann::json::array_t managedBy;
3161 nlohmann::json& manager = managedBy.emplace_back();
3162 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3163 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3164 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3165 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003166
Ed Tanousc1e219d2023-06-07 10:34:33 -07003167 // Fill in SerialConsole info
3168 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3169 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003170
Ed Tanousc1e219d2023-06-07 10:34:33 -07003171 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3172 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3173 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3174 "Press ~. to exit console";
3175 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3176 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003177
3178#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003179 // Fill in GraphicalConsole info
3180 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3181 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3182 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3183 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003184
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003185#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003186
Ed Tanousc1e219d2023-06-07 10:34:33 -07003187 auto health = std::make_shared<HealthPopulate>(asyncResp);
3188 if constexpr (bmcwebEnableHealthPopulate)
3189 {
3190 constexpr std::array<std::string_view, 4> inventoryForSystems{
3191 "xyz.openbmc_project.Inventory.Item.Dimm",
3192 "xyz.openbmc_project.Inventory.Item.Cpu",
3193 "xyz.openbmc_project.Inventory.Item.Drive",
3194 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003195
Ed Tanousc1e219d2023-06-07 10:34:33 -07003196 dbus::utility::getSubTreePaths(
3197 "/", 0, inventoryForSystems,
3198 [health](const boost::system::error_code& ec,
3199 const std::vector<std::string>& resp) {
3200 if (ec)
3201 {
3202 // no inventory
3203 return;
3204 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003205
Ed Tanousc1e219d2023-06-07 10:34:33 -07003206 health->inventory = resp;
3207 });
3208 health->populate();
3209 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003210
Ed Tanousc1e219d2023-06-07 10:34:33 -07003211 getMainChassisId(asyncResp,
3212 [](const std::string& chassisId,
3213 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3214 nlohmann::json::array_t chassisArray;
3215 nlohmann::json& chassis = chassisArray.emplace_back();
3216 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3217 chassisId);
3218 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3219 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003220
Ed Tanousc1e219d2023-06-07 10:34:33 -07003221 getLocationIndicatorActive(asyncResp);
3222 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3223 getIndicatorLedState(asyncResp);
3224 getComputerSystem(asyncResp, health);
3225 getHostState(asyncResp);
3226 getBootProperties(asyncResp);
3227 getBootProgress(asyncResp);
3228 getBootProgressLastStateTime(asyncResp);
3229 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3230 getHostWatchdogTimer(asyncResp);
3231 getPowerRestorePolicy(asyncResp);
3232 getAutomaticRetryPolicy(asyncResp);
3233 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003234#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003235 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003236#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003237 getTrustedModuleRequiredToBoot(asyncResp);
3238 getPowerMode(asyncResp);
3239 getIdlePowerSaver(asyncResp);
3240}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003241
Ed Tanousc1e219d2023-06-07 10:34:33 -07003242inline void handleComputerSystemPatch(
3243 crow::App& app, const crow::Request& req,
3244 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3245 const std::string& systemName)
3246{
3247 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3248 {
3249 return;
3250 }
3251 if constexpr (bmcwebEnableMultiHost)
3252 {
3253 // Option currently returns no systems. TBD
3254 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3255 systemName);
3256 return;
3257 }
3258 if (systemName != "system")
3259 {
3260 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3261 systemName);
3262 return;
3263 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003264
Ed Tanousc1e219d2023-06-07 10:34:33 -07003265 asyncResp->res.addHeader(
3266 boost::beast::http::field::link,
3267 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003268
Ed Tanousc1e219d2023-06-07 10:34:33 -07003269 std::optional<bool> locationIndicatorActive;
3270 std::optional<std::string> indicatorLed;
3271 std::optional<std::string> assetTag;
3272 std::optional<std::string> powerRestorePolicy;
3273 std::optional<std::string> powerMode;
3274 std::optional<bool> wdtEnable;
3275 std::optional<std::string> wdtTimeOutAction;
3276 std::optional<std::string> bootSource;
3277 std::optional<std::string> bootType;
3278 std::optional<std::string> bootEnable;
3279 std::optional<std::string> bootAutomaticRetry;
3280 std::optional<uint32_t> bootAutomaticRetryAttempts;
3281 std::optional<bool> bootTrustedModuleRequired;
3282 std::optional<bool> ipsEnable;
3283 std::optional<uint8_t> ipsEnterUtil;
3284 std::optional<uint64_t> ipsEnterTime;
3285 std::optional<uint8_t> ipsExitUtil;
3286 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003287
Ed Tanousc1e219d2023-06-07 10:34:33 -07003288 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003289 if (!json_util::readJsonPatch(
3290 req, asyncResp->res,
3291 "IndicatorLED", indicatorLed,
3292 "LocationIndicatorActive", locationIndicatorActive,
3293 "AssetTag", assetTag,
3294 "PowerRestorePolicy", powerRestorePolicy,
3295 "PowerMode", powerMode,
3296 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3297 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3298 "Boot/BootSourceOverrideTarget", bootSource,
3299 "Boot/BootSourceOverrideMode", bootType,
3300 "Boot/BootSourceOverrideEnabled", bootEnable,
3301 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003302 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003303 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3304 "IdlePowerSaver/Enabled", ipsEnable,
3305 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3306 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3307 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3308 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3309 {
3310 return;
3311 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003312 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003313
Ed Tanousc1e219d2023-06-07 10:34:33 -07003314 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003315
Ed Tanousc1e219d2023-06-07 10:34:33 -07003316 if (assetTag)
3317 {
3318 setAssetTag(asyncResp, *assetTag);
3319 }
James Feistb49ac872019-05-21 15:12:01 -07003320
Ed Tanousc1e219d2023-06-07 10:34:33 -07003321 if (wdtEnable || wdtTimeOutAction)
3322 {
3323 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3324 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003325
Ed Tanousc1e219d2023-06-07 10:34:33 -07003326 if (bootSource || bootType || bootEnable)
3327 {
3328 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3329 }
3330 if (bootAutomaticRetry)
3331 {
3332 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3333 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003334
Ed Tanousc1e219d2023-06-07 10:34:33 -07003335 if (bootAutomaticRetryAttempts)
3336 {
3337 setAutomaticRetryAttempts(asyncResp,
3338 bootAutomaticRetryAttempts.value());
3339 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003340
Ed Tanousc1e219d2023-06-07 10:34:33 -07003341 if (bootTrustedModuleRequired)
3342 {
3343 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3344 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003345
Ed Tanousc1e219d2023-06-07 10:34:33 -07003346 if (locationIndicatorActive)
3347 {
3348 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3349 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003350
Ed Tanousc1e219d2023-06-07 10:34:33 -07003351 // TODO (Gunnar): Remove IndicatorLED after enough time has
3352 // passed
3353 if (indicatorLed)
3354 {
3355 setIndicatorLedState(asyncResp, *indicatorLed);
3356 asyncResp->res.addHeader(boost::beast::http::field::warning,
3357 "299 - \"IndicatorLED is deprecated. Use "
3358 "LocationIndicatorActive instead.\"");
3359 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003360
Ed Tanousc1e219d2023-06-07 10:34:33 -07003361 if (powerRestorePolicy)
3362 {
3363 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3364 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003365
Ed Tanousc1e219d2023-06-07 10:34:33 -07003366 if (powerMode)
3367 {
3368 setPowerMode(asyncResp, *powerMode);
3369 }
Chris Cain37bbf982021-09-20 10:53:09 -05003370
Ed Tanousc1e219d2023-06-07 10:34:33 -07003371 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3372 {
3373 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3374 ipsExitUtil, ipsExitTime);
3375 }
3376}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303377
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003378inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003379 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003380 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003381 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003382{
3383 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3384 {
3385 return;
3386 }
3387 asyncResp->res.addHeader(
3388 boost::beast::http::field::link,
3389 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3390}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003391inline void handleSystemCollectionResetActionGet(
3392 crow::App& app, const crow::Request& req,
3393 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3394 const std::string& systemName)
3395{
3396 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3397 {
3398 return;
3399 }
3400 if constexpr (bmcwebEnableMultiHost)
3401 {
3402 // Option currently returns no systems. TBD
3403 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3404 systemName);
3405 return;
3406 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003407
Ed Tanousc1e219d2023-06-07 10:34:33 -07003408 if (systemName == "hypervisor")
3409 {
3410 handleHypervisorResetActionGet(asyncResp);
3411 return;
3412 }
3413
3414 if (systemName != "system")
3415 {
3416 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3417 systemName);
3418 return;
3419 }
3420
3421 asyncResp->res.addHeader(
3422 boost::beast::http::field::link,
3423 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3424
3425 asyncResp->res.jsonValue["@odata.id"] =
3426 "/redfish/v1/Systems/system/ResetActionInfo";
3427 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3428 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3429 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3430
3431 nlohmann::json::array_t parameters;
3432 nlohmann::json::object_t parameter;
3433
3434 parameter["Name"] = "ResetType";
3435 parameter["Required"] = true;
3436 parameter["DataType"] = "String";
3437 nlohmann::json::array_t allowableValues;
3438 allowableValues.emplace_back("On");
3439 allowableValues.emplace_back("ForceOff");
3440 allowableValues.emplace_back("ForceOn");
3441 allowableValues.emplace_back("ForceRestart");
3442 allowableValues.emplace_back("GracefulRestart");
3443 allowableValues.emplace_back("GracefulShutdown");
3444 allowableValues.emplace_back("PowerCycle");
3445 allowableValues.emplace_back("Nmi");
3446 parameter["AllowableValues"] = std::move(allowableValues);
3447 parameters.emplace_back(std::move(parameter));
3448
3449 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3450}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303451/**
3452 * SystemResetActionInfo derived class for delivering Computer Systems
3453 * ResetType AllowableValues using ResetInfo schema.
3454 */
Ed Tanous100afe52023-06-07 13:30:46 -07003455inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303456{
Ed Tanous100afe52023-06-07 13:30:46 -07003457 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3458 .privileges(redfish::privileges::headComputerSystemCollection)
3459 .methods(boost::beast::http::verb::head)(
3460 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3461
3462 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3463 .privileges(redfish::privileges::getComputerSystemCollection)
3464 .methods(boost::beast::http::verb::get)(
3465 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3466
3467 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3468 .privileges(redfish::privileges::headComputerSystem)
3469 .methods(boost::beast::http::verb::head)(
3470 std::bind_front(handleComputerSystemHead, std::ref(app)));
3471
3472 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3473 .privileges(redfish::privileges::getComputerSystem)
3474 .methods(boost::beast::http::verb::get)(
3475 std::bind_front(handleComputerSystemGet, std::ref(app)));
3476
3477 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3478 .privileges(redfish::privileges::patchComputerSystem)
3479 .methods(boost::beast::http::verb::patch)(
3480 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3481
3482 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3483 .privileges(redfish::privileges::postComputerSystem)
3484 .methods(boost::beast::http::verb::post)(std::bind_front(
3485 handleComputerSystemResetActionPost, std::ref(app)));
3486
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003487 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003488 .privileges(redfish::privileges::headActionInfo)
3489 .methods(boost::beast::http::verb::head)(std::bind_front(
3490 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003491 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003492 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003493 .methods(boost::beast::http::verb::get)(std::bind_front(
3494 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003495}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003496} // namespace redfish