blob: c30002a8e5c6eb279a2a2dac5c9778a8885e97ec [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/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001411 * @brief Stop Boot On Fault over DBUS.
1412 *
1413 * @param[in] asyncResp Shared pointer for generating response message.
1414 *
1415 * @return None.
1416 */
1417inline void
1418 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1419{
1420 BMCWEB_LOG_DEBUG << "Get Stop Boot On Fault";
1421
1422 sdbusplus::asio::getProperty<bool>(
1423 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1424 "/xyz/openbmc_project/logging/settings",
1425 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1426 [asyncResp](const boost::system::error_code& ec, bool value) {
1427 if (ec)
1428 {
1429 if (ec.value() != EBADR)
1430 {
1431 messages::internalError(asyncResp->res);
1432 }
1433 return;
1434 }
1435
1436 if (value)
1437 {
1438 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1439 }
1440 else
1441 {
1442 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1443 }
1444 });
1445}
1446
1447/**
Ali Ahmed19817712021-06-29 17:01:52 -05001448 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1449 * TPM is required for booting the host.
1450 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001451 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001452 *
1453 * @return None.
1454 */
1455inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001456 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001457{
1458 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001459 constexpr std::array<std::string_view, 1> interfaces = {
1460 "xyz.openbmc_project.Control.TPM.Policy"};
1461 dbus::utility::getSubTree(
1462 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001463 [asyncResp](const boost::system::error_code& ec,
1464 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001465 if (ec)
1466 {
1467 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1468 << ec;
1469 // This is an optional D-Bus object so just return if
1470 // error occurs
1471 return;
1472 }
1473 if (subtree.empty())
1474 {
1475 // As noted above, this is an optional interface so just return
1476 // if there is no instance found
1477 return;
1478 }
1479
1480 /* When there is more than one TPMEnable object... */
1481 if (subtree.size() > 1)
1482 {
1483 BMCWEB_LOG_DEBUG
1484 << "DBUS response has more than 1 TPM Enable object:"
1485 << subtree.size();
1486 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001487 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001488 return;
1489 }
1490
1491 // Make sure the Dbus response map has a service and objectPath
1492 // field
1493 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1494 {
1495 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001496 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001497 return;
1498 }
1499
1500 const std::string& path = subtree[0].first;
1501 const std::string& serv = subtree[0].second.begin()->first;
1502
1503 // Valid TPM Enable object found, now reading the current value
1504 sdbusplus::asio::getProperty<bool>(
1505 *crow::connections::systemBus, serv, path,
1506 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001507 [asyncResp](const boost::system::error_code& ec2,
1508 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001509 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001510 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001511 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001512 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001513 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001514 return;
1515 }
1516
Ed Tanous002d39b2022-05-31 08:59:27 -07001517 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001518 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001519 asyncResp->res
1520 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001521 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001522 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001523 else
1524 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001525 asyncResp->res
1526 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001527 "Disabled";
1528 }
1529 });
George Liue99073f2022-12-09 11:06:16 +08001530 });
Ali Ahmed19817712021-06-29 17:01:52 -05001531}
1532
1533/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001534 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1535 * TPM is required for booting the host.
1536 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001537 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001538 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1539 *
1540 * @return None.
1541 */
1542inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001543 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001544{
1545 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001546 constexpr std::array<std::string_view, 1> interfaces = {
1547 "xyz.openbmc_project.Control.TPM.Policy"};
1548 dbus::utility::getSubTree(
1549 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001550 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001551 tpmRequired](const boost::system::error_code& ec,
1552 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001553 if (ec)
1554 {
1555 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1556 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001557 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001558 return;
1559 }
1560 if (subtree.empty())
1561 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001562 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001563 "TrustedModuleRequiredToBoot");
1564 return;
1565 }
1566
1567 /* When there is more than one TPMEnable object... */
1568 if (subtree.size() > 1)
1569 {
1570 BMCWEB_LOG_DEBUG
1571 << "DBUS response has more than 1 TPM Enable object:"
1572 << subtree.size();
1573 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001574 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001575 return;
1576 }
1577
1578 // Make sure the Dbus response map has a service and objectPath
1579 // field
1580 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1581 {
1582 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001583 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001584 return;
1585 }
1586
1587 const std::string& path = subtree[0].first;
1588 const std::string& serv = subtree[0].second.begin()->first;
1589
1590 if (serv.empty())
1591 {
1592 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001593 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001594 return;
1595 }
1596
1597 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001598 sdbusplus::asio::setProperty(
1599 *crow::connections::systemBus, serv, path,
1600 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001601 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001602 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001603 {
1604 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001605 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001606 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001607 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001608 return;
1609 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001610 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
George Liu9ae226f2023-06-21 17:56:46 +08001611 });
George Liue99073f2022-12-09 11:06:16 +08001612 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001613}
1614
1615/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301616 * @brief Sets boot properties into DBUS object(s).
1617 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001618 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001619 * @param[in] bootType The boot type to set.
1620 * @return Integer error code.
1621 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001622inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001623 const std::optional<std::string>& bootType)
1624{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001625 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001626
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001627 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001628 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001629 return;
1630 }
1631
1632 // Source target specified
1633 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1634 // Figure out which DBUS interface and property to use
1635 if (*bootType == "Legacy")
1636 {
1637 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1638 }
1639 else if (*bootType == "UEFI")
1640 {
1641 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1642 }
1643 else
1644 {
1645 BMCWEB_LOG_DEBUG << "Invalid property value for "
1646 "BootSourceOverrideMode: "
1647 << *bootType;
Ed Tanousac106bf2023-06-07 09:24:59 -07001648 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001649 "BootSourceOverrideMode");
1650 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001651 }
1652
1653 // Act on validated parameters
1654 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1655
George Liu9ae226f2023-06-21 17:56:46 +08001656 sdbusplus::asio::setProperty(
1657 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1658 "/xyz/openbmc_project/control/host0/boot",
1659 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001660 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001661 if (ec)
1662 {
1663 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1664 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001665 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001666 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001667 return;
1668 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001669 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001670 return;
1671 }
1672 BMCWEB_LOG_DEBUG << "Boot type update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001673 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001674}
1675
1676/**
1677 * @brief Sets boot properties into DBUS object(s).
1678 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001679 * @param[in] asyncResp Shared pointer for generating response
1680 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001681 * @param[in] bootType The boot type to set.
1682 * @return Integer error code.
1683 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001684inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001685 const std::optional<std::string>& bootEnable)
1686{
1687 if (!bootEnable)
1688 {
1689 return;
1690 }
1691 // Source target specified
1692 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1693
1694 bool bootOverrideEnable = false;
1695 bool bootOverridePersistent = false;
1696 // Figure out which DBUS interface and property to use
1697 if (*bootEnable == "Disabled")
1698 {
1699 bootOverrideEnable = false;
1700 }
1701 else if (*bootEnable == "Once")
1702 {
1703 bootOverrideEnable = true;
1704 bootOverridePersistent = false;
1705 }
1706 else if (*bootEnable == "Continuous")
1707 {
1708 bootOverrideEnable = true;
1709 bootOverridePersistent = true;
1710 }
1711 else
1712 {
George Liu0fda0f12021-11-16 10:06:17 +08001713 BMCWEB_LOG_DEBUG
1714 << "Invalid property value for BootSourceOverrideEnabled: "
1715 << *bootEnable;
Ed Tanousac106bf2023-06-07 09:24:59 -07001716 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001717 "BootSourceOverrideEnabled");
1718 return;
1719 }
1720
1721 // Act on validated parameters
1722 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1723
George Liu9ae226f2023-06-21 17:56:46 +08001724 sdbusplus::asio::setProperty(
1725 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1726 "/xyz/openbmc_project/control/host0/boot",
1727 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001728 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001729 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001730 {
Ed Tanous8a592812022-06-04 09:06:59 -07001731 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001732 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001733 return;
1734 }
1735 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001736 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001737
1738 if (!bootOverrideEnable)
1739 {
1740 return;
1741 }
1742
1743 // In case boot override is enabled we need to set correct value for the
1744 // 'one_time' enable DBus interface
1745 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1746 << bootOverridePersistent;
1747
George Liu9ae226f2023-06-21 17:56:46 +08001748 sdbusplus::asio::setProperty(
1749 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1750 "/xyz/openbmc_project/control/host0/boot/one_time",
1751 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001752 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001753 if (ec)
1754 {
1755 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001756 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001757 return;
1758 }
1759 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001760 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001761}
1762
1763/**
1764 * @brief Sets boot properties into DBUS object(s).
1765 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001766 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301767 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301768 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001769 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301770 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001771inline void
1772 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1773 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301774{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001775 std::string bootSourceStr;
1776 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001777
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001778 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301779 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001780 return;
1781 }
1782
1783 // Source target specified
1784 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1785 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001786 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1787 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001788 {
1789 BMCWEB_LOG_DEBUG
1790 << "Invalid property value for BootSourceOverrideTarget: "
1791 << *bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -07001792 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001793 "BootSourceTargetOverride");
1794 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001795 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301796
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001797 // Act on validated parameters
1798 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1799 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001800
George Liu9ae226f2023-06-21 17:56:46 +08001801 sdbusplus::asio::setProperty(
1802 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1803 "/xyz/openbmc_project/control/host0/boot",
1804 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001805 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001806 if (ec)
1807 {
1808 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001809 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001810 return;
1811 }
1812 BMCWEB_LOG_DEBUG << "Boot source update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001813 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001814
George Liu9ae226f2023-06-21 17:56:46 +08001815 sdbusplus::asio::setProperty(
1816 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1817 "/xyz/openbmc_project/control/host0/boot",
1818 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001819 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001820 if (ec)
1821 {
1822 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001823 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001824 return;
1825 }
1826 BMCWEB_LOG_DEBUG << "Boot mode update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001827 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001828}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001829
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001830/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001831 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301832 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001833 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301834 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001835 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301836 * @param[in] bootEnable The boot override enable from incoming RF request.
1837 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001838 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301839 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001840
Ed Tanousac106bf2023-06-07 09:24:59 -07001841inline void
1842 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1843 const std::optional<std::string>& bootSource,
1844 const std::optional<std::string>& bootType,
1845 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301846{
1847 BMCWEB_LOG_DEBUG << "Set boot information.";
1848
Ed Tanousac106bf2023-06-07 09:24:59 -07001849 setBootModeOrSource(asyncResp, bootSource);
1850 setBootType(asyncResp, bootType);
1851 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301852}
1853
George Liuc6a620f2020-04-10 17:18:11 +08001854/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001855 * @brief Sets AssetTag
1856 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001857 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001858 * @param[in] assetTag "AssetTag" from request.
1859 *
1860 * @return None.
1861 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001862inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001863 const std::string& assetTag)
1864{
George Liue99073f2022-12-09 11:06:16 +08001865 constexpr std::array<std::string_view, 1> interfaces = {
1866 "xyz.openbmc_project.Inventory.Item.System"};
1867 dbus::utility::getSubTree(
1868 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001869 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001870 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001871 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001872 if (ec)
1873 {
1874 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001875 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001876 return;
1877 }
1878 if (subtree.empty())
1879 {
1880 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001881 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001882 return;
1883 }
1884 // Assume only 1 system D-Bus object
1885 // Throw an error if there is more than 1
1886 if (subtree.size() > 1)
1887 {
1888 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001889 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001890 return;
1891 }
1892 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1893 {
1894 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001895 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001896 return;
1897 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001898
Ed Tanous002d39b2022-05-31 08:59:27 -07001899 const std::string& path = subtree[0].first;
1900 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001901
Ed Tanous002d39b2022-05-31 08:59:27 -07001902 if (service.empty())
1903 {
1904 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001905 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001906 return;
1907 }
1908
George Liu9ae226f2023-06-21 17:56:46 +08001909 sdbusplus::asio::setProperty(
1910 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001911 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001912 assetTag, [asyncResp](const boost::system::error_code& ec2) {
1913 if (ec2)
1914 {
1915 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1916 << ec2;
1917 messages::internalError(asyncResp->res);
1918 return;
1919 }
1920 });
George Liue99073f2022-12-09 11:06:16 +08001921 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001922}
1923
1924/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001925 * @brief Validate the specified stopBootOnFault is valid and return the
1926 * stopBootOnFault name associated with that string
1927 *
1928 * @param[in] stopBootOnFaultString String representing the desired
1929 * stopBootOnFault
1930 *
1931 * @return stopBootOnFault value or empty if incoming value is not valid
1932 */
1933inline std::optional<bool>
1934 validstopBootOnFault(const std::string& stopBootOnFaultString)
1935{
1936 if (stopBootOnFaultString == "AnyFault")
1937 {
1938 return true;
1939 }
1940
1941 if (stopBootOnFaultString == "Never")
1942 {
1943 return false;
1944 }
1945
1946 return std::nullopt;
1947}
1948
1949/**
1950 * @brief Sets stopBootOnFault
1951 *
1952 * @param[in] aResp Shared pointer for generating response message.
1953 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1954 *
1955 * @return None.
1956 */
1957inline void setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1958 const std::string& stopBootOnFault)
1959{
1960 BMCWEB_LOG_DEBUG << "Set Stop Boot On Fault.";
1961
1962 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1963 if (!stopBootEnabled)
1964 {
1965 BMCWEB_LOG_DEBUG << "Invalid property value for StopBootOnFault: "
1966 << stopBootOnFault;
1967 messages::propertyValueNotInList(aResp->res, stopBootOnFault,
1968 "StopBootOnFault");
1969 return;
1970 }
1971
1972 sdbusplus::asio::setProperty(*crow::connections::systemBus,
1973 "xyz.openbmc_project.Settings",
1974 "/xyz/openbmc_project/logging/settings",
1975 "xyz.openbmc_project.Logging.Settings",
1976 "QuiesceOnHwError", *stopBootEnabled,
1977 [aResp](const boost::system::error_code& ec) {
1978 if (ec)
1979 {
1980 if (ec.value() != EBADR)
1981 {
1982 messages::internalError(aResp->res);
1983 }
1984 return;
1985 }
1986 });
1987}
1988
1989/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001990 * @brief Sets automaticRetry (Auto Reboot)
1991 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001992 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001993 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1994 *
1995 * @return None.
1996 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001997inline void
1998 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1999 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05002000{
2001 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
2002
2003 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002004 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002005
2006 if (automaticRetryConfig == "Disabled")
2007 {
2008 autoRebootEnabled = false;
2009 }
2010 else if (automaticRetryConfig == "RetryAttempts")
2011 {
2012 autoRebootEnabled = true;
2013 }
2014 else
2015 {
George Liu0fda0f12021-11-16 10:06:17 +08002016 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05002017 << automaticRetryConfig;
Ed Tanousac106bf2023-06-07 09:24:59 -07002018 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002019 "AutomaticRetryConfig");
2020 return;
2021 }
2022
George Liu9ae226f2023-06-21 17:56:46 +08002023 sdbusplus::asio::setProperty(
2024 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002025 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002026 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002027 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
2028 if (ec)
2029 {
2030 messages::internalError(asyncResp->res);
2031 return;
2032 }
2033 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002034}
2035
Ed Tanous8d69c662023-06-21 10:29:06 -07002036inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2037{
2038 if (policy == "AlwaysOn")
2039 {
2040 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2041 }
2042 if (policy == "AlwaysOff")
2043 {
2044 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2045 }
2046 if (policy == "LastState")
2047 {
2048 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2049 }
2050 return "";
2051}
2052
Gunnar Mills69f35302020-05-17 16:06:31 -05002053/**
George Liuc6a620f2020-04-10 17:18:11 +08002054 * @brief Sets power restore policy properties.
2055 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002056 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002057 * @param[in] policy power restore policy properties from request.
2058 *
2059 * @return None.
2060 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002061inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002062 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002063 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002064{
2065 BMCWEB_LOG_DEBUG << "Set power restore policy.";
2066
Ed Tanous8d69c662023-06-21 10:29:06 -07002067 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002068
Ed Tanous8d69c662023-06-21 10:29:06 -07002069 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002070 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002071 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002072 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002073 return;
2074 }
2075
George Liu9ae226f2023-06-21 17:56:46 +08002076 sdbusplus::asio::setProperty(
2077 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002078 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002079 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002080 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2081 if (ec)
2082 {
2083 messages::internalError(asyncResp->res);
2084 return;
2085 }
2086 });
George Liuc6a620f2020-04-10 17:18:11 +08002087}
2088
AppaRao Pulia6349912019-10-18 17:16:08 +05302089#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2090/**
2091 * @brief Retrieves provisioning status
2092 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002093 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302094 *
2095 * @return None.
2096 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002097inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302098{
2099 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002100 sdbusplus::asio::getAllProperties(
2101 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2102 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002103 [asyncResp](const boost::system::error_code& ec,
2104 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002105 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002106 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2107 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002108 "#OemComputerSystem.OpenBmc";
2109 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002110
Ed Tanous002d39b2022-05-31 08:59:27 -07002111 if (ec)
2112 {
2113 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2114 // not an error, don't have to have the interface
2115 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2116 return;
2117 }
2118
2119 const bool* provState = nullptr;
2120 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002121
2122 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002123 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2124 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002125
2126 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002127 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002128 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002129 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002130 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302131
Ed Tanous002d39b2022-05-31 08:59:27 -07002132 if ((provState == nullptr) || (lockState == nullptr))
2133 {
2134 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
Ed Tanousac106bf2023-06-07 09:24:59 -07002135 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002136 return;
2137 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302138
Ed Tanous002d39b2022-05-31 08:59:27 -07002139 if (*provState == true)
2140 {
2141 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302142 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002143 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302144 }
2145 else
2146 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002147 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302148 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002149 }
2150 else
2151 {
2152 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2153 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002154 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302155}
2156#endif
2157
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302158/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002159 * @brief Translate the PowerMode to a response message.
2160 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002161 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002162 * @param[in] modeValue PowerMode value to be translated
2163 *
2164 * @return None.
2165 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002166inline void
2167 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2168 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002169{
George Liu0fda0f12021-11-16 10:06:17 +08002170 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002171 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002172 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002173 }
George Liu0fda0f12021-11-16 10:06:17 +08002174 else if (
2175 modeValue ==
2176 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002177 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002178 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002179 }
George Liu0fda0f12021-11-16 10:06:17 +08002180 else if (modeValue ==
2181 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002182 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002183 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002184 }
George Liu0fda0f12021-11-16 10:06:17 +08002185 else if (modeValue ==
2186 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002187 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002188 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002189 }
2190 else
2191 {
2192 // Any other values would be invalid
2193 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
Ed Tanousac106bf2023-06-07 09:24:59 -07002194 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002195 }
2196}
2197
2198/**
2199 * @brief Retrieves system power mode
2200 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002201 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002202 *
2203 * @return None.
2204 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002205inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002206{
2207 BMCWEB_LOG_DEBUG << "Get power mode.";
2208
2209 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002210 constexpr std::array<std::string_view, 1> interfaces = {
2211 "xyz.openbmc_project.Control.Power.Mode"};
2212 dbus::utility::getSubTree(
2213 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002214 [asyncResp](const boost::system::error_code& ec,
2215 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002216 if (ec)
2217 {
2218 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2219 << ec;
2220 // This is an optional D-Bus object so just return if
2221 // error occurs
2222 return;
2223 }
2224 if (subtree.empty())
2225 {
2226 // As noted above, this is an optional interface so just return
2227 // if there is no instance found
2228 return;
2229 }
2230 if (subtree.size() > 1)
2231 {
2232 // More then one PowerMode object is not supported and is an
2233 // error
2234 BMCWEB_LOG_DEBUG
2235 << "Found more than 1 system D-Bus Power.Mode objects: "
2236 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002237 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002238 return;
2239 }
2240 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2241 {
2242 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002243 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002244 return;
2245 }
2246 const std::string& path = subtree[0].first;
2247 const std::string& service = subtree[0].second.begin()->first;
2248 if (service.empty())
2249 {
2250 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002251 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002252 return;
2253 }
2254 // Valid Power Mode object found, now read the current value
2255 sdbusplus::asio::getProperty<std::string>(
2256 *crow::connections::systemBus, service, path,
2257 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002258 [asyncResp](const boost::system::error_code& ec2,
2259 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002260 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002261 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002262 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002263 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002264 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002265 return;
2266 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002267
Ed Tanousac106bf2023-06-07 09:24:59 -07002268 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002269 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002270
Ed Tanous002d39b2022-05-31 08:59:27 -07002271 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
Ed Tanousac106bf2023-06-07 09:24:59 -07002272 translatePowerMode(asyncResp, pmode);
Ed Tanous002d39b2022-05-31 08:59:27 -07002273 });
George Liue99073f2022-12-09 11:06:16 +08002274 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002275}
2276
2277/**
2278 * @brief Validate the specified mode is valid and return the PowerMode
2279 * name associated with that string
2280 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002281 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002282 * @param[in] modeString String representing the desired PowerMode
2283 *
2284 * @return PowerMode value or empty string if mode is not valid
2285 */
2286inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002287 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002288 const std::string& modeString)
2289{
2290 std::string mode;
2291
2292 if (modeString == "Static")
2293 {
2294 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2295 }
2296 else if (modeString == "MaximumPerformance")
2297 {
George Liu0fda0f12021-11-16 10:06:17 +08002298 mode =
2299 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002300 }
2301 else if (modeString == "PowerSaving")
2302 {
2303 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2304 }
2305 else
2306 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002307 messages::propertyValueNotInList(asyncResp->res, modeString,
2308 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002309 }
2310 return mode;
2311}
2312
2313/**
2314 * @brief Sets system power mode.
2315 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002316 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002317 * @param[in] pmode System power mode from request.
2318 *
2319 * @return None.
2320 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002321inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002322 const std::string& pmode)
2323{
2324 BMCWEB_LOG_DEBUG << "Set power mode.";
2325
Ed Tanousac106bf2023-06-07 09:24:59 -07002326 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002327 if (powerMode.empty())
2328 {
2329 return;
2330 }
2331
2332 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002333 constexpr std::array<std::string_view, 1> interfaces = {
2334 "xyz.openbmc_project.Control.Power.Mode"};
2335 dbus::utility::getSubTree(
2336 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002337 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002338 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002339 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002340 if (ec)
2341 {
2342 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2343 << ec;
2344 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002345 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002346 return;
2347 }
2348 if (subtree.empty())
2349 {
2350 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002351 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002352 "PowerMode");
2353 return;
2354 }
2355 if (subtree.size() > 1)
2356 {
2357 // More then one PowerMode object is not supported and is an
2358 // error
2359 BMCWEB_LOG_DEBUG
2360 << "Found more than 1 system D-Bus Power.Mode objects: "
2361 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002362 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002363 return;
2364 }
2365 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2366 {
2367 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002368 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002369 return;
2370 }
2371 const std::string& path = subtree[0].first;
2372 const std::string& service = subtree[0].second.begin()->first;
2373 if (service.empty())
2374 {
2375 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002376 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002377 return;
2378 }
2379
2380 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2381 << path;
2382
2383 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002384 sdbusplus::asio::setProperty(
2385 *crow::connections::systemBus, service, path,
2386 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002387 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002388 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002389 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002390 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002391 return;
2392 }
George Liu9ae226f2023-06-21 17:56:46 +08002393 });
George Liue99073f2022-12-09 11:06:16 +08002394 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002395}
2396
2397/**
Yong Li51709ff2019-09-30 14:13:04 +08002398 * @brief Translates watchdog timeout action DBUS property value to redfish.
2399 *
2400 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2401 *
2402 * @return Returns as a string, the timeout action in Redfish terms. If
2403 * translation cannot be done, returns an empty string.
2404 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002405inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002406{
2407 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2408 {
2409 return "None";
2410 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002411 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002412 {
2413 return "ResetSystem";
2414 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002415 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002416 {
2417 return "PowerDown";
2418 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002419 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002420 {
2421 return "PowerCycle";
2422 }
2423
2424 return "";
2425}
2426
2427/**
Yong Lic45f0082019-10-10 14:19:01 +08002428 *@brief Translates timeout action from Redfish to DBUS property value.
2429 *
2430 *@param[in] rfAction The timeout action in Redfish.
2431 *
2432 *@return Returns as a string, the time_out action as expected by DBUS.
2433 *If translation cannot be done, returns an empty string.
2434 */
2435
Ed Tanous23a21a12020-07-25 04:45:05 +00002436inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002437{
2438 if (rfAction == "None")
2439 {
2440 return "xyz.openbmc_project.State.Watchdog.Action.None";
2441 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002442 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002443 {
2444 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2445 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002446 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002447 {
2448 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2449 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002450 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002451 {
2452 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2453 }
2454
2455 return "";
2456}
2457
2458/**
Yong Li51709ff2019-09-30 14:13:04 +08002459 * @brief Retrieves host watchdog timer properties over DBUS
2460 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002461 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002462 *
2463 * @return None.
2464 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002465inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002466 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002467{
2468 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002469 sdbusplus::asio::getAllProperties(
2470 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2471 "/xyz/openbmc_project/watchdog/host0",
2472 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002473 [asyncResp](const boost::system::error_code& ec,
2474 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002475 if (ec)
2476 {
2477 // watchdog service is stopped
2478 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2479 return;
2480 }
2481
2482 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2483
2484 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002485 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002486
2487 // watchdog service is running/enabled
2488 hostWatchdogTimer["Status"]["State"] = "Enabled";
2489
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002490 const bool* enabled = nullptr;
2491 const std::string* expireAction = nullptr;
2492
2493 const bool success = sdbusplus::unpackPropertiesNoThrow(
2494 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2495 "ExpireAction", expireAction);
2496
2497 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002498 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002499 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002500 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002501 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002502
2503 if (enabled != nullptr)
2504 {
2505 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2506 }
2507
2508 if (expireAction != nullptr)
2509 {
2510 std::string action = dbusToRfWatchdogAction(*expireAction);
2511 if (action.empty())
2512 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002513 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002514 return;
2515 }
2516 hostWatchdogTimer["TimeoutAction"] = action;
2517 }
2518 });
Yong Li51709ff2019-09-30 14:13:04 +08002519}
2520
2521/**
Yong Lic45f0082019-10-10 14:19:01 +08002522 * @brief Sets Host WatchDog Timer properties.
2523 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002524 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002525 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2526 * RF request.
2527 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2528 *
2529 * @return None.
2530 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002531inline void
2532 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2533 const std::optional<bool> wdtEnable,
2534 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002535{
2536 BMCWEB_LOG_DEBUG << "Set host watchdog";
2537
2538 if (wdtTimeOutAction)
2539 {
2540 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2541 // check if TimeOut Action is Valid
2542 if (wdtTimeOutActStr.empty())
2543 {
2544 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2545 << *wdtTimeOutAction;
Ed Tanousac106bf2023-06-07 09:24:59 -07002546 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002547 "TimeoutAction");
2548 return;
2549 }
2550
George Liu9ae226f2023-06-21 17:56:46 +08002551 sdbusplus::asio::setProperty(
2552 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002553 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002554 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002555 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2556 if (ec)
2557 {
2558 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2559 messages::internalError(asyncResp->res);
2560 return;
2561 }
2562 });
Yong Lic45f0082019-10-10 14:19:01 +08002563 }
2564
2565 if (wdtEnable)
2566 {
George Liu9ae226f2023-06-21 17:56:46 +08002567 sdbusplus::asio::setProperty(
2568 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2569 "/xyz/openbmc_project/watchdog/host0",
2570 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002571 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002572 if (ec)
2573 {
2574 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002575 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002576 return;
2577 }
George Liu9ae226f2023-06-21 17:56:46 +08002578 });
Yong Lic45f0082019-10-10 14:19:01 +08002579 }
2580}
2581
Chris Cain37bbf982021-09-20 10:53:09 -05002582/**
2583 * @brief Parse the Idle Power Saver properties into json
2584 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002585 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002586 * @param[in] properties IPS property data from DBus.
2587 *
2588 * @return true if successful
2589 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002590inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002591 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002592 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002593{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002594 const bool* enabled = nullptr;
2595 const uint8_t* enterUtilizationPercent = nullptr;
2596 const uint64_t* enterDwellTime = nullptr;
2597 const uint8_t* exitUtilizationPercent = nullptr;
2598 const uint64_t* exitDwellTime = nullptr;
2599
2600 const bool success = sdbusplus::unpackPropertiesNoThrow(
2601 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002602 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2603 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2604 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002605
2606 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002607 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002608 return false;
2609 }
2610
2611 if (enabled != nullptr)
2612 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002613 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002614 }
2615
2616 if (enterUtilizationPercent != nullptr)
2617 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002618 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002619 *enterUtilizationPercent;
2620 }
2621
2622 if (enterDwellTime != nullptr)
2623 {
2624 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002625 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002626 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2627 .count();
2628 }
2629
2630 if (exitUtilizationPercent != nullptr)
2631 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002632 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002633 *exitUtilizationPercent;
2634 }
2635
2636 if (exitDwellTime != nullptr)
2637 {
2638 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002639 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002640 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2641 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002642 }
2643
2644 return true;
2645}
2646
2647/**
2648 * @brief Retrieves host watchdog timer properties over DBUS
2649 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002650 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002651 *
2652 * @return None.
2653 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002654inline void
2655 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002656{
2657 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2658
2659 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002660 constexpr std::array<std::string_view, 1> interfaces = {
2661 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2662 dbus::utility::getSubTree(
2663 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002664 [asyncResp](const boost::system::error_code& ec,
2665 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002666 if (ec)
2667 {
2668 BMCWEB_LOG_DEBUG
2669 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2670 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002671 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002672 return;
2673 }
2674 if (subtree.empty())
2675 {
2676 // This is an optional interface so just return
2677 // if there is no instance found
2678 BMCWEB_LOG_DEBUG << "No instances found";
2679 return;
2680 }
2681 if (subtree.size() > 1)
2682 {
2683 // More then one PowerIdlePowerSaver object is not supported and
2684 // is an error
2685 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2686 "Power.IdlePowerSaver objects: "
2687 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002688 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002689 return;
2690 }
2691 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2692 {
2693 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002694 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002695 return;
2696 }
2697 const std::string& path = subtree[0].first;
2698 const std::string& service = subtree[0].second.begin()->first;
2699 if (service.empty())
2700 {
2701 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002702 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002703 return;
2704 }
2705
2706 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002707 sdbusplus::asio::getAllProperties(
2708 *crow::connections::systemBus, service, path,
2709 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002710 [asyncResp](const boost::system::error_code& ec2,
2711 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002712 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002713 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002714 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002715 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002716 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002717 return;
2718 }
2719
Ed Tanousac106bf2023-06-07 09:24:59 -07002720 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002721 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002722 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002723 return;
2724 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002725 });
George Liue99073f2022-12-09 11:06:16 +08002726 });
Chris Cain37bbf982021-09-20 10:53:09 -05002727
2728 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2729}
2730
2731/**
2732 * @brief Sets Idle Power Saver properties.
2733 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002734 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002735 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2736 * RF request.
2737 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2738 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2739 * before entering idle state.
2740 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2741 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2742 * before exiting idle state
2743 *
2744 * @return None.
2745 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002746inline void
2747 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2748 const std::optional<bool> ipsEnable,
2749 const std::optional<uint8_t> ipsEnterUtil,
2750 const std::optional<uint64_t> ipsEnterTime,
2751 const std::optional<uint8_t> ipsExitUtil,
2752 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002753{
2754 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2755
2756 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002757 constexpr std::array<std::string_view, 1> interfaces = {
2758 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2759 dbus::utility::getSubTree(
2760 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002761 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002762 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002763 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002764 if (ec)
2765 {
2766 BMCWEB_LOG_DEBUG
2767 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2768 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002769 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002770 return;
2771 }
2772 if (subtree.empty())
2773 {
2774 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002775 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002776 "IdlePowerSaver");
2777 return;
2778 }
2779 if (subtree.size() > 1)
2780 {
2781 // More then one PowerIdlePowerSaver object is not supported and
2782 // is an error
2783 BMCWEB_LOG_DEBUG
2784 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2785 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002786 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002787 return;
2788 }
2789 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2790 {
2791 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002792 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002793 return;
2794 }
2795 const std::string& path = subtree[0].first;
2796 const std::string& service = subtree[0].second.begin()->first;
2797 if (service.empty())
2798 {
2799 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002800 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002801 return;
2802 }
Chris Cain37bbf982021-09-20 10:53:09 -05002803
Ed Tanous002d39b2022-05-31 08:59:27 -07002804 // Valid Power IdlePowerSaver object found, now set any values that
2805 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002806
Ed Tanous002d39b2022-05-31 08:59:27 -07002807 if (ipsEnable)
2808 {
George Liu9ae226f2023-06-21 17:56:46 +08002809 sdbusplus::asio::setProperty(
2810 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002811 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002812 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
2813 if (ec2)
2814 {
2815 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2816 messages::internalError(asyncResp->res);
2817 return;
2818 }
2819 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002820 }
2821 if (ipsEnterUtil)
2822 {
George Liu9ae226f2023-06-21 17:56:46 +08002823 sdbusplus::asio::setProperty(
2824 *crow::connections::systemBus, service, path,
2825 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2826 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002827 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002828 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002829 {
Ed Tanous8a592812022-06-04 09:06:59 -07002830 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002831 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002832 return;
2833 }
George Liu9ae226f2023-06-21 17:56:46 +08002834 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002835 }
2836 if (ipsEnterTime)
2837 {
2838 // Convert from seconds into milliseconds for DBus
2839 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002840 sdbusplus::asio::setProperty(
2841 *crow::connections::systemBus, service, path,
2842 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2843 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002844 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002845 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002846 {
Ed Tanous8a592812022-06-04 09:06:59 -07002847 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002848 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002849 return;
2850 }
George Liu9ae226f2023-06-21 17:56:46 +08002851 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002852 }
2853 if (ipsExitUtil)
2854 {
George Liu9ae226f2023-06-21 17:56:46 +08002855 sdbusplus::asio::setProperty(
2856 *crow::connections::systemBus, service, path,
2857 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2858 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002859 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002860 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002861 {
Ed Tanous8a592812022-06-04 09:06:59 -07002862 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002863 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002864 return;
2865 }
George Liu9ae226f2023-06-21 17:56:46 +08002866 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002867 }
2868 if (ipsExitTime)
2869 {
2870 // Convert from seconds into milliseconds for DBus
2871 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002872 sdbusplus::asio::setProperty(
2873 *crow::connections::systemBus, service, path,
2874 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2875 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002876 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002877 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002878 {
Ed Tanous8a592812022-06-04 09:06:59 -07002879 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002880 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002881 return;
2882 }
George Liu9ae226f2023-06-21 17:56:46 +08002883 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002884 }
George Liue99073f2022-12-09 11:06:16 +08002885 });
Chris Cain37bbf982021-09-20 10:53:09 -05002886
2887 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2888}
2889
Ed Tanousc1e219d2023-06-07 10:34:33 -07002890inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002891 crow::App& app, const crow::Request& req,
2892 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2893{
2894 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2895 {
2896 return;
2897 }
2898 asyncResp->res.addHeader(
2899 boost::beast::http::field::link,
2900 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2901}
2902
Ed Tanousc1e219d2023-06-07 10:34:33 -07002903inline void handleComputerSystemCollectionGet(
2904 crow::App& app, const crow::Request& req,
2905 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2906{
2907 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2908 {
2909 return;
2910 }
2911
2912 asyncResp->res.addHeader(
2913 boost::beast::http::field::link,
2914 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2915 asyncResp->res.jsonValue["@odata.type"] =
2916 "#ComputerSystemCollection.ComputerSystemCollection";
2917 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2918 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2919
2920 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2921 ifaceArray = nlohmann::json::array();
2922 if constexpr (bmcwebEnableMultiHost)
2923 {
2924 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2925 // Option currently returns no systems. TBD
2926 return;
2927 }
2928 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2929 nlohmann::json::object_t system;
2930 system["@odata.id"] = "/redfish/v1/Systems/system";
2931 ifaceArray.emplace_back(std::move(system));
2932 sdbusplus::asio::getProperty<std::string>(
2933 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2934 "/xyz/openbmc_project/network/hypervisor",
2935 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2936 [asyncResp](const boost::system::error_code& ec2,
2937 const std::string& /*hostName*/) {
2938 if (ec2)
2939 {
2940 return;
2941 }
2942 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2943 if (val == asyncResp->res.jsonValue.end())
2944 {
2945 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2946 return;
2947 }
2948 uint64_t* count = val->get_ptr<uint64_t*>();
2949 if (count == nullptr)
2950 {
2951 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2952 return;
2953 }
2954 *count = *count + 1;
2955 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2956 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2957 nlohmann::json::object_t hypervisor;
2958 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2959 ifaceArray2.emplace_back(std::move(hypervisor));
2960 });
2961}
2962
Yong Lic45f0082019-10-10 14:19:01 +08002963/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002964 * Function transceives data with dbus directly.
2965 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002966inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002967{
Patrick Williams89492a12023-05-10 07:51:34 -05002968 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2969 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2970 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002971 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002972 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002973
2974 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002975 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002976 if (ec)
2977 {
2978 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2979 messages::internalError(asyncResp->res);
2980 return;
2981 }
2982 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002983 },
2984 serviceName, objectPath, interfaceName, method);
2985}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002986
2987/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002988 * Handle error responses from d-bus for system power requests
2989 */
2990inline void handleSystemActionResetError(const boost::system::error_code& ec,
2991 const sdbusplus::message_t& eMsg,
2992 std::string_view resetType,
2993 crow::Response& res)
2994{
2995 if (ec.value() == boost::asio::error::invalid_argument)
2996 {
2997 messages::actionParameterNotSupported(res, resetType, "Reset");
2998 return;
2999 }
3000
3001 if (eMsg.get_error() == nullptr)
3002 {
3003 BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
3004 messages::internalError(res);
3005 return;
3006 }
3007 std::string_view errorMessage = eMsg.get_error()->name;
3008
3009 // If operation failed due to BMC not being in Ready state, tell
3010 // user to retry in a bit
3011 if ((errorMessage ==
3012 std::string_view(
3013 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3014 (errorMessage ==
3015 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3016 {
3017 BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
3018 messages::serviceTemporarilyUnavailable(res, "10");
3019 return;
3020 }
3021
3022 BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
3023 << " sdbusplus:" << errorMessage;
3024 messages::internalError(res);
3025}
3026
Ed Tanousc1e219d2023-06-07 10:34:33 -07003027inline void handleComputerSystemResetActionPost(
3028 crow::App& app, const crow::Request& req,
3029 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3030 const std::string& systemName)
3031{
3032 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3033 {
3034 return;
3035 }
3036 if (systemName != "system")
3037 {
3038 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3039 systemName);
3040 return;
3041 }
3042 if constexpr (bmcwebEnableMultiHost)
3043 {
3044 // Option currently returns no systems. TBD
3045 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3046 systemName);
3047 return;
3048 }
3049 std::string resetType;
3050 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3051 {
3052 return;
3053 }
3054
3055 // Get the command and host vs. chassis
3056 std::string command;
3057 bool hostCommand = true;
3058 if ((resetType == "On") || (resetType == "ForceOn"))
3059 {
3060 command = "xyz.openbmc_project.State.Host.Transition.On";
3061 hostCommand = true;
3062 }
3063 else if (resetType == "ForceOff")
3064 {
3065 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3066 hostCommand = false;
3067 }
3068 else if (resetType == "ForceRestart")
3069 {
3070 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3071 hostCommand = true;
3072 }
3073 else if (resetType == "GracefulShutdown")
3074 {
3075 command = "xyz.openbmc_project.State.Host.Transition.Off";
3076 hostCommand = true;
3077 }
3078 else if (resetType == "GracefulRestart")
3079 {
3080 command =
3081 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3082 hostCommand = true;
3083 }
3084 else if (resetType == "PowerCycle")
3085 {
3086 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3087 hostCommand = true;
3088 }
3089 else if (resetType == "Nmi")
3090 {
3091 doNMI(asyncResp);
3092 return;
3093 }
3094 else
3095 {
3096 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3097 return;
3098 }
3099
3100 if (hostCommand)
3101 {
George Liu9ae226f2023-06-21 17:56:46 +08003102 sdbusplus::asio::setProperty(
3103 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3104 "/xyz/openbmc_project/state/host0",
3105 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3106 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003107 [asyncResp, resetType](const boost::system::error_code& ec,
3108 sdbusplus::message_t& sdbusErrMsg) {
3109 if (ec)
3110 {
3111 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3112 asyncResp->res);
3113
3114 return;
3115 }
3116 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003117 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003118 }
3119 else
3120 {
George Liu9ae226f2023-06-21 17:56:46 +08003121 sdbusplus::asio::setProperty(
3122 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3123 "/xyz/openbmc_project/state/chassis0",
3124 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3125 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003126 [asyncResp, resetType](const boost::system::error_code& ec,
3127 sdbusplus::message_t& sdbusErrMsg) {
3128 if (ec)
3129 {
3130 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3131 asyncResp->res);
3132 return;
3133 }
3134 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003135 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003136 }
3137}
3138
Ed Tanousc1e219d2023-06-07 10:34:33 -07003139inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003140 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003141 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3142 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003143{
3144 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3145 {
3146 return;
3147 }
3148
3149 asyncResp->res.addHeader(
3150 boost::beast::http::field::link,
3151 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3152}
3153
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003154inline void afterPortRequest(
3155 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3156 const boost::system::error_code& ec,
3157 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3158{
3159 if (ec)
3160 {
3161 messages::internalError(asyncResp->res);
3162 return;
3163 }
3164 for (const auto& data : socketData)
3165 {
3166 const std::string& socketPath = get<0>(data);
3167 const std::string& protocolName = get<1>(data);
3168 bool isProtocolEnabled = get<2>(data);
3169 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3170 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3171 // need to retrieve port number for
3172 // obmc-console-ssh service
3173 if (protocolName == "SSH")
3174 {
3175 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003176 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003177 int portNumber) {
3178 if (ec1)
3179 {
3180 messages::internalError(asyncResp->res);
3181 return;
3182 }
3183 nlohmann::json& dataJson1 =
3184 asyncResp->res.jsonValue["SerialConsole"];
3185 dataJson1[protocolName]["Port"] = portNumber;
3186 });
3187 }
3188 }
3189}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003190
3191inline void
3192 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3193 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3194 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003195{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003196 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3197 {
3198 return;
3199 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003200
Ed Tanousc1e219d2023-06-07 10:34:33 -07003201 if constexpr (bmcwebEnableMultiHost)
3202 {
3203 // Option currently returns no systems. TBD
3204 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3205 systemName);
3206 return;
3207 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003208
Ed Tanousc1e219d2023-06-07 10:34:33 -07003209 if (systemName == "hypervisor")
3210 {
3211 handleHypervisorSystemGet(asyncResp);
3212 return;
3213 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003214
Ed Tanousc1e219d2023-06-07 10:34:33 -07003215 if (systemName != "system")
3216 {
3217 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3218 systemName);
3219 return;
3220 }
3221 asyncResp->res.addHeader(
3222 boost::beast::http::field::link,
3223 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3224 asyncResp->res.jsonValue["@odata.type"] =
3225 "#ComputerSystem.v1_16_0.ComputerSystem";
3226 asyncResp->res.jsonValue["Name"] = "system";
3227 asyncResp->res.jsonValue["Id"] = "system";
3228 asyncResp->res.jsonValue["SystemType"] = "Physical";
3229 asyncResp->res.jsonValue["Description"] = "Computer System";
3230 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3231 if constexpr (bmcwebEnableProcMemStatus)
3232 {
3233 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3234 "Disabled";
3235 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3236 "Disabled";
3237 }
3238 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3239 uint64_t(0);
3240 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003241
Ed Tanousc1e219d2023-06-07 10:34:33 -07003242 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3243 "/redfish/v1/Systems/system/Processors";
3244 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3245 "/redfish/v1/Systems/system/Memory";
3246 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3247 "/redfish/v1/Systems/system/Storage";
3248 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3249 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003250
Ed Tanousc1e219d2023-06-07 10:34:33 -07003251 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3252 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3253 asyncResp->res
3254 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3255 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003256
Ed Tanousc1e219d2023-06-07 10:34:33 -07003257 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3258 "/redfish/v1/Systems/system/LogServices";
3259 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3260 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003261
Ed Tanousc1e219d2023-06-07 10:34:33 -07003262 nlohmann::json::array_t managedBy;
3263 nlohmann::json& manager = managedBy.emplace_back();
3264 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3265 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3266 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3267 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003268
Ed Tanousc1e219d2023-06-07 10:34:33 -07003269 // Fill in SerialConsole info
3270 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3271 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003272
Ed Tanousc1e219d2023-06-07 10:34:33 -07003273 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3274 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3275 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3276 "Press ~. to exit console";
3277 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3278 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003279
3280#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003281 // Fill in GraphicalConsole info
3282 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3283 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3284 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3285 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003286
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003287#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003288
Ed Tanousc1e219d2023-06-07 10:34:33 -07003289 auto health = std::make_shared<HealthPopulate>(asyncResp);
3290 if constexpr (bmcwebEnableHealthPopulate)
3291 {
3292 constexpr std::array<std::string_view, 4> inventoryForSystems{
3293 "xyz.openbmc_project.Inventory.Item.Dimm",
3294 "xyz.openbmc_project.Inventory.Item.Cpu",
3295 "xyz.openbmc_project.Inventory.Item.Drive",
3296 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003297
Ed Tanousc1e219d2023-06-07 10:34:33 -07003298 dbus::utility::getSubTreePaths(
3299 "/", 0, inventoryForSystems,
3300 [health](const boost::system::error_code& ec,
3301 const std::vector<std::string>& resp) {
3302 if (ec)
3303 {
3304 // no inventory
3305 return;
3306 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003307
Ed Tanousc1e219d2023-06-07 10:34:33 -07003308 health->inventory = resp;
3309 });
3310 health->populate();
3311 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003312
Ed Tanousc1e219d2023-06-07 10:34:33 -07003313 getMainChassisId(asyncResp,
3314 [](const std::string& chassisId,
3315 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3316 nlohmann::json::array_t chassisArray;
3317 nlohmann::json& chassis = chassisArray.emplace_back();
3318 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3319 chassisId);
3320 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3321 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003322
Ed Tanousc1e219d2023-06-07 10:34:33 -07003323 getLocationIndicatorActive(asyncResp);
3324 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3325 getIndicatorLedState(asyncResp);
3326 getComputerSystem(asyncResp, health);
3327 getHostState(asyncResp);
3328 getBootProperties(asyncResp);
3329 getBootProgress(asyncResp);
3330 getBootProgressLastStateTime(asyncResp);
3331 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3332 getHostWatchdogTimer(asyncResp);
3333 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003334 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003335 getAutomaticRetryPolicy(asyncResp);
3336 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003337#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003338 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003339#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003340 getTrustedModuleRequiredToBoot(asyncResp);
3341 getPowerMode(asyncResp);
3342 getIdlePowerSaver(asyncResp);
3343}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003344
Ed Tanousc1e219d2023-06-07 10:34:33 -07003345inline void handleComputerSystemPatch(
3346 crow::App& app, const crow::Request& req,
3347 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3348 const std::string& systemName)
3349{
3350 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3351 {
3352 return;
3353 }
3354 if constexpr (bmcwebEnableMultiHost)
3355 {
3356 // Option currently returns no systems. TBD
3357 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3358 systemName);
3359 return;
3360 }
3361 if (systemName != "system")
3362 {
3363 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3364 systemName);
3365 return;
3366 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003367
Ed Tanousc1e219d2023-06-07 10:34:33 -07003368 asyncResp->res.addHeader(
3369 boost::beast::http::field::link,
3370 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003371
Ed Tanousc1e219d2023-06-07 10:34:33 -07003372 std::optional<bool> locationIndicatorActive;
3373 std::optional<std::string> indicatorLed;
3374 std::optional<std::string> assetTag;
3375 std::optional<std::string> powerRestorePolicy;
3376 std::optional<std::string> powerMode;
3377 std::optional<bool> wdtEnable;
3378 std::optional<std::string> wdtTimeOutAction;
3379 std::optional<std::string> bootSource;
3380 std::optional<std::string> bootType;
3381 std::optional<std::string> bootEnable;
3382 std::optional<std::string> bootAutomaticRetry;
3383 std::optional<uint32_t> bootAutomaticRetryAttempts;
3384 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003385 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003386 std::optional<bool> ipsEnable;
3387 std::optional<uint8_t> ipsEnterUtil;
3388 std::optional<uint64_t> ipsEnterTime;
3389 std::optional<uint8_t> ipsExitUtil;
3390 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003391
Ed Tanousc1e219d2023-06-07 10:34:33 -07003392 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003393 if (!json_util::readJsonPatch(
3394 req, asyncResp->res,
3395 "IndicatorLED", indicatorLed,
3396 "LocationIndicatorActive", locationIndicatorActive,
3397 "AssetTag", assetTag,
3398 "PowerRestorePolicy", powerRestorePolicy,
3399 "PowerMode", powerMode,
3400 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3401 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3402 "Boot/BootSourceOverrideTarget", bootSource,
3403 "Boot/BootSourceOverrideMode", bootType,
3404 "Boot/BootSourceOverrideEnabled", bootEnable,
3405 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003406 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003407 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003408 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003409 "IdlePowerSaver/Enabled", ipsEnable,
3410 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3411 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3412 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3413 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3414 {
3415 return;
3416 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003417 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003418
Ed Tanousc1e219d2023-06-07 10:34:33 -07003419 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003420
Ed Tanousc1e219d2023-06-07 10:34:33 -07003421 if (assetTag)
3422 {
3423 setAssetTag(asyncResp, *assetTag);
3424 }
James Feistb49ac872019-05-21 15:12:01 -07003425
Ed Tanousc1e219d2023-06-07 10:34:33 -07003426 if (wdtEnable || wdtTimeOutAction)
3427 {
3428 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3429 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003430
Ed Tanousc1e219d2023-06-07 10:34:33 -07003431 if (bootSource || bootType || bootEnable)
3432 {
3433 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3434 }
3435 if (bootAutomaticRetry)
3436 {
3437 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3438 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003439
Ed Tanousc1e219d2023-06-07 10:34:33 -07003440 if (bootAutomaticRetryAttempts)
3441 {
3442 setAutomaticRetryAttempts(asyncResp,
3443 bootAutomaticRetryAttempts.value());
3444 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003445
Ed Tanousc1e219d2023-06-07 10:34:33 -07003446 if (bootTrustedModuleRequired)
3447 {
3448 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3449 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003450
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003451 if (stopBootOnFault)
3452 {
3453 setStopBootOnFault(asyncResp, *stopBootOnFault);
3454 }
3455
Ed Tanousc1e219d2023-06-07 10:34:33 -07003456 if (locationIndicatorActive)
3457 {
3458 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3459 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003460
Ed Tanousc1e219d2023-06-07 10:34:33 -07003461 // TODO (Gunnar): Remove IndicatorLED after enough time has
3462 // passed
3463 if (indicatorLed)
3464 {
3465 setIndicatorLedState(asyncResp, *indicatorLed);
3466 asyncResp->res.addHeader(boost::beast::http::field::warning,
3467 "299 - \"IndicatorLED is deprecated. Use "
3468 "LocationIndicatorActive instead.\"");
3469 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003470
Ed Tanousc1e219d2023-06-07 10:34:33 -07003471 if (powerRestorePolicy)
3472 {
3473 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3474 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003475
Ed Tanousc1e219d2023-06-07 10:34:33 -07003476 if (powerMode)
3477 {
3478 setPowerMode(asyncResp, *powerMode);
3479 }
Chris Cain37bbf982021-09-20 10:53:09 -05003480
Ed Tanousc1e219d2023-06-07 10:34:33 -07003481 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3482 {
3483 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3484 ipsExitUtil, ipsExitTime);
3485 }
3486}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303487
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003488inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003489 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003490 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003491 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003492{
3493 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3494 {
3495 return;
3496 }
3497 asyncResp->res.addHeader(
3498 boost::beast::http::field::link,
3499 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3500}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003501inline void handleSystemCollectionResetActionGet(
3502 crow::App& app, const crow::Request& req,
3503 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3504 const std::string& systemName)
3505{
3506 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3507 {
3508 return;
3509 }
3510 if constexpr (bmcwebEnableMultiHost)
3511 {
3512 // Option currently returns no systems. TBD
3513 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3514 systemName);
3515 return;
3516 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003517
Ed Tanousc1e219d2023-06-07 10:34:33 -07003518 if (systemName == "hypervisor")
3519 {
3520 handleHypervisorResetActionGet(asyncResp);
3521 return;
3522 }
3523
3524 if (systemName != "system")
3525 {
3526 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3527 systemName);
3528 return;
3529 }
3530
3531 asyncResp->res.addHeader(
3532 boost::beast::http::field::link,
3533 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3534
3535 asyncResp->res.jsonValue["@odata.id"] =
3536 "/redfish/v1/Systems/system/ResetActionInfo";
3537 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3538 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3539 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3540
3541 nlohmann::json::array_t parameters;
3542 nlohmann::json::object_t parameter;
3543
3544 parameter["Name"] = "ResetType";
3545 parameter["Required"] = true;
3546 parameter["DataType"] = "String";
3547 nlohmann::json::array_t allowableValues;
3548 allowableValues.emplace_back("On");
3549 allowableValues.emplace_back("ForceOff");
3550 allowableValues.emplace_back("ForceOn");
3551 allowableValues.emplace_back("ForceRestart");
3552 allowableValues.emplace_back("GracefulRestart");
3553 allowableValues.emplace_back("GracefulShutdown");
3554 allowableValues.emplace_back("PowerCycle");
3555 allowableValues.emplace_back("Nmi");
3556 parameter["AllowableValues"] = std::move(allowableValues);
3557 parameters.emplace_back(std::move(parameter));
3558
3559 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3560}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303561/**
3562 * SystemResetActionInfo derived class for delivering Computer Systems
3563 * ResetType AllowableValues using ResetInfo schema.
3564 */
Ed Tanous100afe52023-06-07 13:30:46 -07003565inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303566{
Ed Tanous100afe52023-06-07 13:30:46 -07003567 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3568 .privileges(redfish::privileges::headComputerSystemCollection)
3569 .methods(boost::beast::http::verb::head)(
3570 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3571
3572 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3573 .privileges(redfish::privileges::getComputerSystemCollection)
3574 .methods(boost::beast::http::verb::get)(
3575 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3576
3577 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3578 .privileges(redfish::privileges::headComputerSystem)
3579 .methods(boost::beast::http::verb::head)(
3580 std::bind_front(handleComputerSystemHead, std::ref(app)));
3581
3582 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3583 .privileges(redfish::privileges::getComputerSystem)
3584 .methods(boost::beast::http::verb::get)(
3585 std::bind_front(handleComputerSystemGet, std::ref(app)));
3586
3587 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3588 .privileges(redfish::privileges::patchComputerSystem)
3589 .methods(boost::beast::http::verb::patch)(
3590 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3591
3592 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3593 .privileges(redfish::privileges::postComputerSystem)
3594 .methods(boost::beast::http::verb::post)(std::bind_front(
3595 handleComputerSystemResetActionPost, std::ref(app)));
3596
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003597 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003598 .privileges(redfish::privileges::headActionInfo)
3599 .methods(boost::beast::http::verb::head)(std::bind_front(
3600 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003601 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003602 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003603 .methods(boost::beast::http::verb::get)(std::bind_front(
3604 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003605}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003606} // namespace redfish