blob: 70f887090a2d2da63a05a9e8b15df015bd31db7e [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.";
1335 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001336 [asyncResp](const boost::system::error_code& ec) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001337 if (ec)
1338 {
1339 BMCWEB_LOG_ERROR
1340 << "DBUS response error: Set setAutomaticRetryAttempts" << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001341 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001342 return;
1343 }
1344 },
1345 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
1346 "org.freedesktop.DBus.Properties", "Set",
1347 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
1348 std::variant<uint32_t>(retryAttempts));
1349}
1350
Ed Tanous8d69c662023-06-21 10:29:06 -07001351inline computer_system::PowerRestorePolicyTypes
1352 redfishPowerRestorePolicyFromDbus(std::string_view value)
1353{
1354 if (value ==
1355 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1356 {
1357 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1358 }
1359 if (value ==
1360 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1361 {
1362 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1363 }
1364 if (value ==
1365 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore")
1366 {
1367 return computer_system::PowerRestorePolicyTypes::LastState;
1368 }
1369 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1370 {
1371 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1372 }
1373 return computer_system::PowerRestorePolicyTypes::Invalid;
1374}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001375/**
George Liuc6a620f2020-04-10 17:18:11 +08001376 * @brief Retrieves power restore policy over DBUS.
1377 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001378 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001379 *
1380 * @return None.
1381 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001382inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001383 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001384{
1385 BMCWEB_LOG_DEBUG << "Get power restore policy";
1386
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001387 sdbusplus::asio::getProperty<std::string>(
1388 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1389 "/xyz/openbmc_project/control/host0/power_restore_policy",
1390 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001391 [asyncResp](const boost::system::error_code& ec,
1392 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001393 if (ec)
1394 {
1395 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1396 return;
1397 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001398 computer_system::PowerRestorePolicyTypes restore =
1399 redfishPowerRestorePolicyFromDbus(policy);
1400 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001401 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001402 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001403 return;
1404 }
George Liuc6a620f2020-04-10 17:18:11 +08001405
Ed Tanous8d69c662023-06-21 10:29:06 -07001406 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001407 });
George Liuc6a620f2020-04-10 17:18:11 +08001408}
1409
1410/**
Ali Ahmed19817712021-06-29 17:01:52 -05001411 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1412 * TPM is required for booting the host.
1413 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001414 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001415 *
1416 * @return None.
1417 */
1418inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001419 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001420{
1421 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001422 constexpr std::array<std::string_view, 1> interfaces = {
1423 "xyz.openbmc_project.Control.TPM.Policy"};
1424 dbus::utility::getSubTree(
1425 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001426 [asyncResp](const boost::system::error_code& ec,
1427 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001428 if (ec)
1429 {
1430 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1431 << ec;
1432 // This is an optional D-Bus object so just return if
1433 // error occurs
1434 return;
1435 }
1436 if (subtree.empty())
1437 {
1438 // As noted above, this is an optional interface so just return
1439 // if there is no instance found
1440 return;
1441 }
1442
1443 /* When there is more than one TPMEnable object... */
1444 if (subtree.size() > 1)
1445 {
1446 BMCWEB_LOG_DEBUG
1447 << "DBUS response has more than 1 TPM Enable object:"
1448 << subtree.size();
1449 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001450 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001451 return;
1452 }
1453
1454 // Make sure the Dbus response map has a service and objectPath
1455 // field
1456 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1457 {
1458 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001459 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001460 return;
1461 }
1462
1463 const std::string& path = subtree[0].first;
1464 const std::string& serv = subtree[0].second.begin()->first;
1465
1466 // Valid TPM Enable object found, now reading the current value
1467 sdbusplus::asio::getProperty<bool>(
1468 *crow::connections::systemBus, serv, path,
1469 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001470 [asyncResp](const boost::system::error_code& ec2,
1471 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001472 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001473 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001474 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001475 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001476 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001477 return;
1478 }
1479
Ed Tanous002d39b2022-05-31 08:59:27 -07001480 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001481 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001482 asyncResp->res
1483 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001484 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001485 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001486 else
1487 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001488 asyncResp->res
1489 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001490 "Disabled";
1491 }
1492 });
George Liue99073f2022-12-09 11:06:16 +08001493 });
Ali Ahmed19817712021-06-29 17:01:52 -05001494}
1495
1496/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001497 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1498 * TPM is required for booting the host.
1499 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001500 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001501 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1502 *
1503 * @return None.
1504 */
1505inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001506 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001507{
1508 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001509 constexpr std::array<std::string_view, 1> interfaces = {
1510 "xyz.openbmc_project.Control.TPM.Policy"};
1511 dbus::utility::getSubTree(
1512 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001513 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001514 tpmRequired](const boost::system::error_code& ec,
1515 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001516 if (ec)
1517 {
1518 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1519 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001520 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001521 return;
1522 }
1523 if (subtree.empty())
1524 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001525 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001526 "TrustedModuleRequiredToBoot");
1527 return;
1528 }
1529
1530 /* When there is more than one TPMEnable object... */
1531 if (subtree.size() > 1)
1532 {
1533 BMCWEB_LOG_DEBUG
1534 << "DBUS response has more than 1 TPM Enable object:"
1535 << subtree.size();
1536 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001537 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001538 return;
1539 }
1540
1541 // Make sure the Dbus response map has a service and objectPath
1542 // field
1543 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1544 {
1545 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001546 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001547 return;
1548 }
1549
1550 const std::string& path = subtree[0].first;
1551 const std::string& serv = subtree[0].second.begin()->first;
1552
1553 if (serv.empty())
1554 {
1555 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001556 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001557 return;
1558 }
1559
1560 // Valid TPM Enable object found, now setting the value
1561 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001562 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001563 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001564 {
1565 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001566 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001567 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001568 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001569 return;
1570 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001571 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1572 },
1573 serv, path, "org.freedesktop.DBus.Properties", "Set",
1574 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1575 dbus::utility::DbusVariantType(tpmRequired));
George Liue99073f2022-12-09 11:06:16 +08001576 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001577}
1578
1579/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301580 * @brief Sets boot properties into DBUS object(s).
1581 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001582 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001583 * @param[in] bootType The boot type to set.
1584 * @return Integer error code.
1585 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001586inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001587 const std::optional<std::string>& bootType)
1588{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001589 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001590
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001591 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001592 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001593 return;
1594 }
1595
1596 // Source target specified
1597 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1598 // Figure out which DBUS interface and property to use
1599 if (*bootType == "Legacy")
1600 {
1601 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1602 }
1603 else if (*bootType == "UEFI")
1604 {
1605 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1606 }
1607 else
1608 {
1609 BMCWEB_LOG_DEBUG << "Invalid property value for "
1610 "BootSourceOverrideMode: "
1611 << *bootType;
Ed Tanousac106bf2023-06-07 09:24:59 -07001612 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001613 "BootSourceOverrideMode");
1614 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001615 }
1616
1617 // Act on validated parameters
1618 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1619
1620 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001621 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001622 if (ec)
1623 {
1624 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1625 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001626 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001627 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001628 return;
1629 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001630 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001631 return;
1632 }
1633 BMCWEB_LOG_DEBUG << "Boot type update done.";
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001634 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001635 "xyz.openbmc_project.Settings",
1636 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001637 "org.freedesktop.DBus.Properties", "Set",
1638 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001639 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001640}
1641
1642/**
1643 * @brief Sets boot properties into DBUS object(s).
1644 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001645 * @param[in] asyncResp Shared pointer for generating response
1646 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001647 * @param[in] bootType The boot type to set.
1648 * @return Integer error code.
1649 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001650inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001651 const std::optional<std::string>& bootEnable)
1652{
1653 if (!bootEnable)
1654 {
1655 return;
1656 }
1657 // Source target specified
1658 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1659
1660 bool bootOverrideEnable = false;
1661 bool bootOverridePersistent = false;
1662 // Figure out which DBUS interface and property to use
1663 if (*bootEnable == "Disabled")
1664 {
1665 bootOverrideEnable = false;
1666 }
1667 else if (*bootEnable == "Once")
1668 {
1669 bootOverrideEnable = true;
1670 bootOverridePersistent = false;
1671 }
1672 else if (*bootEnable == "Continuous")
1673 {
1674 bootOverrideEnable = true;
1675 bootOverridePersistent = true;
1676 }
1677 else
1678 {
George Liu0fda0f12021-11-16 10:06:17 +08001679 BMCWEB_LOG_DEBUG
1680 << "Invalid property value for BootSourceOverrideEnabled: "
1681 << *bootEnable;
Ed Tanousac106bf2023-06-07 09:24:59 -07001682 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001683 "BootSourceOverrideEnabled");
1684 return;
1685 }
1686
1687 // Act on validated parameters
1688 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1689
1690 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001691 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001692 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001693 {
Ed Tanous8a592812022-06-04 09:06:59 -07001694 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001695 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001696 return;
1697 }
1698 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001699 },
1700 "xyz.openbmc_project.Settings",
1701 "/xyz/openbmc_project/control/host0/boot",
1702 "org.freedesktop.DBus.Properties", "Set",
1703 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001704 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001705
1706 if (!bootOverrideEnable)
1707 {
1708 return;
1709 }
1710
1711 // In case boot override is enabled we need to set correct value for the
1712 // 'one_time' enable DBus interface
1713 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1714 << bootOverridePersistent;
1715
1716 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001717 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001718 if (ec)
1719 {
1720 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001721 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001722 return;
1723 }
1724 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001725 },
1726 "xyz.openbmc_project.Settings",
1727 "/xyz/openbmc_project/control/host0/boot/one_time",
1728 "org.freedesktop.DBus.Properties", "Set",
1729 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001730 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001731}
1732
1733/**
1734 * @brief Sets boot properties into DBUS object(s).
1735 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001736 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301737 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301738 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001739 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301740 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001741inline void
1742 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1743 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301744{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001745 std::string bootSourceStr;
1746 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001747
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001748 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301749 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001750 return;
1751 }
1752
1753 // Source target specified
1754 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1755 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001756 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1757 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001758 {
1759 BMCWEB_LOG_DEBUG
1760 << "Invalid property value for BootSourceOverrideTarget: "
1761 << *bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -07001762 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001763 "BootSourceTargetOverride");
1764 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001765 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301766
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001767 // Act on validated parameters
1768 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1769 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001770
1771 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001772 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001773 if (ec)
1774 {
1775 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001776 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001777 return;
1778 }
1779 BMCWEB_LOG_DEBUG << "Boot source update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001780 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001781 "xyz.openbmc_project.Settings",
1782 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001783 "org.freedesktop.DBus.Properties", "Set",
1784 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001785 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001786
1787 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001788 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001789 if (ec)
1790 {
1791 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001792 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001793 return;
1794 }
1795 BMCWEB_LOG_DEBUG << "Boot mode update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001796 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001797 "xyz.openbmc_project.Settings",
1798 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001799 "org.freedesktop.DBus.Properties", "Set",
1800 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001801 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001802}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001803
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001804/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001805 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301806 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001807 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301808 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001809 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301810 * @param[in] bootEnable The boot override enable from incoming RF request.
1811 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001812 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301813 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001814
Ed Tanousac106bf2023-06-07 09:24:59 -07001815inline void
1816 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1817 const std::optional<std::string>& bootSource,
1818 const std::optional<std::string>& bootType,
1819 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301820{
1821 BMCWEB_LOG_DEBUG << "Set boot information.";
1822
Ed Tanousac106bf2023-06-07 09:24:59 -07001823 setBootModeOrSource(asyncResp, bootSource);
1824 setBootType(asyncResp, bootType);
1825 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301826}
1827
George Liuc6a620f2020-04-10 17:18:11 +08001828/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001829 * @brief Sets AssetTag
1830 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001831 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001832 * @param[in] assetTag "AssetTag" from request.
1833 *
1834 * @return None.
1835 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001836inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001837 const std::string& assetTag)
1838{
George Liue99073f2022-12-09 11:06:16 +08001839 constexpr std::array<std::string_view, 1> interfaces = {
1840 "xyz.openbmc_project.Inventory.Item.System"};
1841 dbus::utility::getSubTree(
1842 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001843 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001844 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001845 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001846 if (ec)
1847 {
1848 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001849 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001850 return;
1851 }
1852 if (subtree.empty())
1853 {
1854 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001855 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001856 return;
1857 }
1858 // Assume only 1 system D-Bus object
1859 // Throw an error if there is more than 1
1860 if (subtree.size() > 1)
1861 {
1862 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001863 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001864 return;
1865 }
1866 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1867 {
1868 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001869 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001870 return;
1871 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001872
Ed Tanous002d39b2022-05-31 08:59:27 -07001873 const std::string& path = subtree[0].first;
1874 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001875
Ed Tanous002d39b2022-05-31 08:59:27 -07001876 if (service.empty())
1877 {
1878 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001879 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001880 return;
1881 }
1882
1883 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001884 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001885 if (ec2)
Gunnar Mills98e386e2020-10-30 14:58:09 -05001886 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001887 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1888 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001889 messages::internalError(asyncResp->res);
Gunnar Mills98e386e2020-10-30 14:58:09 -05001890 return;
1891 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001892 },
1893 service, path, "org.freedesktop.DBus.Properties", "Set",
1894 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1895 dbus::utility::DbusVariantType(assetTag));
George Liue99073f2022-12-09 11:06:16 +08001896 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001897}
1898
1899/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001900 * @brief Sets automaticRetry (Auto Reboot)
1901 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001902 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001903 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1904 *
1905 * @return None.
1906 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001907inline void
1908 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1909 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001910{
1911 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1912
1913 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001914 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001915
1916 if (automaticRetryConfig == "Disabled")
1917 {
1918 autoRebootEnabled = false;
1919 }
1920 else if (automaticRetryConfig == "RetryAttempts")
1921 {
1922 autoRebootEnabled = true;
1923 }
1924 else
1925 {
George Liu0fda0f12021-11-16 10:06:17 +08001926 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001927 << automaticRetryConfig;
Ed Tanousac106bf2023-06-07 09:24:59 -07001928 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001929 "AutomaticRetryConfig");
1930 return;
1931 }
1932
1933 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001934 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001935 if (ec)
1936 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001937 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001938 return;
1939 }
Gunnar Mills69f35302020-05-17 16:06:31 -05001940 },
1941 "xyz.openbmc_project.Settings",
1942 "/xyz/openbmc_project/control/host0/auto_reboot",
1943 "org.freedesktop.DBus.Properties", "Set",
1944 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous168e20c2021-12-13 14:39:53 -08001945 dbus::utility::DbusVariantType(autoRebootEnabled));
Gunnar Mills69f35302020-05-17 16:06:31 -05001946}
1947
Ed Tanous8d69c662023-06-21 10:29:06 -07001948inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1949{
1950 if (policy == "AlwaysOn")
1951 {
1952 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1953 }
1954 if (policy == "AlwaysOff")
1955 {
1956 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1957 }
1958 if (policy == "LastState")
1959 {
1960 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1961 }
1962 return "";
1963}
1964
Gunnar Mills69f35302020-05-17 16:06:31 -05001965/**
George Liuc6a620f2020-04-10 17:18:11 +08001966 * @brief Sets power restore policy properties.
1967 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001968 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001969 * @param[in] policy power restore policy properties from request.
1970 *
1971 * @return None.
1972 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001973inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001974 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001975 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08001976{
1977 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1978
Ed Tanous8d69c662023-06-21 10:29:06 -07001979 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001980
Ed Tanous8d69c662023-06-21 10:29:06 -07001981 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08001982 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001983 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06001984 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001985 return;
1986 }
1987
George Liuc6a620f2020-04-10 17:18:11 +08001988 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07001989 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001990 if (ec)
1991 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001992 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001993 return;
1994 }
George Liuc6a620f2020-04-10 17:18:11 +08001995 },
1996 "xyz.openbmc_project.Settings",
1997 "/xyz/openbmc_project/control/host0/power_restore_policy",
1998 "org.freedesktop.DBus.Properties", "Set",
1999 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous8d69c662023-06-21 10:29:06 -07002000 dbus::utility::DbusVariantType(powerRestorePolicy));
George Liuc6a620f2020-04-10 17:18:11 +08002001}
2002
AppaRao Pulia6349912019-10-18 17:16:08 +05302003#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2004/**
2005 * @brief Retrieves provisioning status
2006 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002007 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302008 *
2009 * @return None.
2010 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002011inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302012{
2013 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002014 sdbusplus::asio::getAllProperties(
2015 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2016 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002017 [asyncResp](const boost::system::error_code& ec,
2018 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002019 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002020 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2021 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002022 "#OemComputerSystem.OpenBmc";
2023 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002024
Ed Tanous002d39b2022-05-31 08:59:27 -07002025 if (ec)
2026 {
2027 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2028 // not an error, don't have to have the interface
2029 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2030 return;
2031 }
2032
2033 const bool* provState = nullptr;
2034 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002035
2036 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002037 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2038 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002039
2040 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002041 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002042 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002043 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002044 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302045
Ed Tanous002d39b2022-05-31 08:59:27 -07002046 if ((provState == nullptr) || (lockState == nullptr))
2047 {
2048 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
Ed Tanousac106bf2023-06-07 09:24:59 -07002049 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002050 return;
2051 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302052
Ed Tanous002d39b2022-05-31 08:59:27 -07002053 if (*provState == true)
2054 {
2055 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302056 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002057 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302058 }
2059 else
2060 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002061 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302062 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002063 }
2064 else
2065 {
2066 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2067 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002068 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302069}
2070#endif
2071
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302072/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002073 * @brief Translate the PowerMode to a response message.
2074 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002075 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002076 * @param[in] modeValue PowerMode value to be translated
2077 *
2078 * @return None.
2079 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002080inline void
2081 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2082 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002083{
George Liu0fda0f12021-11-16 10:06:17 +08002084 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002085 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002086 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002087 }
George Liu0fda0f12021-11-16 10:06:17 +08002088 else if (
2089 modeValue ==
2090 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002091 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002092 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002093 }
George Liu0fda0f12021-11-16 10:06:17 +08002094 else if (modeValue ==
2095 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002096 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002097 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002098 }
George Liu0fda0f12021-11-16 10:06:17 +08002099 else if (modeValue ==
2100 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002101 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002102 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002103 }
2104 else
2105 {
2106 // Any other values would be invalid
2107 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
Ed Tanousac106bf2023-06-07 09:24:59 -07002108 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002109 }
2110}
2111
2112/**
2113 * @brief Retrieves system power mode
2114 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002115 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002116 *
2117 * @return None.
2118 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002119inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002120{
2121 BMCWEB_LOG_DEBUG << "Get power mode.";
2122
2123 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002124 constexpr std::array<std::string_view, 1> interfaces = {
2125 "xyz.openbmc_project.Control.Power.Mode"};
2126 dbus::utility::getSubTree(
2127 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002128 [asyncResp](const boost::system::error_code& ec,
2129 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002130 if (ec)
2131 {
2132 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2133 << ec;
2134 // This is an optional D-Bus object so just return if
2135 // error occurs
2136 return;
2137 }
2138 if (subtree.empty())
2139 {
2140 // As noted above, this is an optional interface so just return
2141 // if there is no instance found
2142 return;
2143 }
2144 if (subtree.size() > 1)
2145 {
2146 // More then one PowerMode object is not supported and is an
2147 // error
2148 BMCWEB_LOG_DEBUG
2149 << "Found more than 1 system D-Bus Power.Mode objects: "
2150 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002151 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002152 return;
2153 }
2154 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2155 {
2156 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002157 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002158 return;
2159 }
2160 const std::string& path = subtree[0].first;
2161 const std::string& service = subtree[0].second.begin()->first;
2162 if (service.empty())
2163 {
2164 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002165 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002166 return;
2167 }
2168 // Valid Power Mode object found, now read the current value
2169 sdbusplus::asio::getProperty<std::string>(
2170 *crow::connections::systemBus, service, path,
2171 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002172 [asyncResp](const boost::system::error_code& ec2,
2173 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002174 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002175 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002176 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002177 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002178 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002179 return;
2180 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002181
Ed Tanousac106bf2023-06-07 09:24:59 -07002182 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002183 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002184
Ed Tanous002d39b2022-05-31 08:59:27 -07002185 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
Ed Tanousac106bf2023-06-07 09:24:59 -07002186 translatePowerMode(asyncResp, pmode);
Ed Tanous002d39b2022-05-31 08:59:27 -07002187 });
George Liue99073f2022-12-09 11:06:16 +08002188 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002189}
2190
2191/**
2192 * @brief Validate the specified mode is valid and return the PowerMode
2193 * name associated with that string
2194 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002195 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002196 * @param[in] modeString String representing the desired PowerMode
2197 *
2198 * @return PowerMode value or empty string if mode is not valid
2199 */
2200inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002201 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002202 const std::string& modeString)
2203{
2204 std::string mode;
2205
2206 if (modeString == "Static")
2207 {
2208 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2209 }
2210 else if (modeString == "MaximumPerformance")
2211 {
George Liu0fda0f12021-11-16 10:06:17 +08002212 mode =
2213 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002214 }
2215 else if (modeString == "PowerSaving")
2216 {
2217 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2218 }
2219 else
2220 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002221 messages::propertyValueNotInList(asyncResp->res, modeString,
2222 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002223 }
2224 return mode;
2225}
2226
2227/**
2228 * @brief Sets system power mode.
2229 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002230 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002231 * @param[in] pmode System power mode from request.
2232 *
2233 * @return None.
2234 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002235inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002236 const std::string& pmode)
2237{
2238 BMCWEB_LOG_DEBUG << "Set power mode.";
2239
Ed Tanousac106bf2023-06-07 09:24:59 -07002240 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002241 if (powerMode.empty())
2242 {
2243 return;
2244 }
2245
2246 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002247 constexpr std::array<std::string_view, 1> interfaces = {
2248 "xyz.openbmc_project.Control.Power.Mode"};
2249 dbus::utility::getSubTree(
2250 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002251 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002252 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002253 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002254 if (ec)
2255 {
2256 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2257 << ec;
2258 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002259 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002260 return;
2261 }
2262 if (subtree.empty())
2263 {
2264 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002265 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002266 "PowerMode");
2267 return;
2268 }
2269 if (subtree.size() > 1)
2270 {
2271 // More then one PowerMode object is not supported and is an
2272 // error
2273 BMCWEB_LOG_DEBUG
2274 << "Found more than 1 system D-Bus Power.Mode objects: "
2275 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002276 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002277 return;
2278 }
2279 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2280 {
2281 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002283 return;
2284 }
2285 const std::string& path = subtree[0].first;
2286 const std::string& service = subtree[0].second.begin()->first;
2287 if (service.empty())
2288 {
2289 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002290 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002291 return;
2292 }
2293
2294 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2295 << path;
2296
2297 // Set the Power Mode property
2298 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002299 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002300 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002301 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002302 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002303 return;
2304 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002305 },
2306 service, path, "org.freedesktop.DBus.Properties", "Set",
2307 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2308 dbus::utility::DbusVariantType(powerMode));
George Liue99073f2022-12-09 11:06:16 +08002309 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002310}
2311
2312/**
Yong Li51709ff2019-09-30 14:13:04 +08002313 * @brief Translates watchdog timeout action DBUS property value to redfish.
2314 *
2315 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2316 *
2317 * @return Returns as a string, the timeout action in Redfish terms. If
2318 * translation cannot be done, returns an empty string.
2319 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002320inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002321{
2322 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2323 {
2324 return "None";
2325 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002326 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002327 {
2328 return "ResetSystem";
2329 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002330 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002331 {
2332 return "PowerDown";
2333 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002334 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002335 {
2336 return "PowerCycle";
2337 }
2338
2339 return "";
2340}
2341
2342/**
Yong Lic45f0082019-10-10 14:19:01 +08002343 *@brief Translates timeout action from Redfish to DBUS property value.
2344 *
2345 *@param[in] rfAction The timeout action in Redfish.
2346 *
2347 *@return Returns as a string, the time_out action as expected by DBUS.
2348 *If translation cannot be done, returns an empty string.
2349 */
2350
Ed Tanous23a21a12020-07-25 04:45:05 +00002351inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002352{
2353 if (rfAction == "None")
2354 {
2355 return "xyz.openbmc_project.State.Watchdog.Action.None";
2356 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002357 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002358 {
2359 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2360 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002361 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002362 {
2363 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2364 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002365 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002366 {
2367 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2368 }
2369
2370 return "";
2371}
2372
2373/**
Yong Li51709ff2019-09-30 14:13:04 +08002374 * @brief Retrieves host watchdog timer properties over DBUS
2375 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002376 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002377 *
2378 * @return None.
2379 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002380inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002381 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002382{
2383 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002384 sdbusplus::asio::getAllProperties(
2385 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2386 "/xyz/openbmc_project/watchdog/host0",
2387 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002388 [asyncResp](const boost::system::error_code& ec,
2389 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002390 if (ec)
2391 {
2392 // watchdog service is stopped
2393 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2394 return;
2395 }
2396
2397 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2398
2399 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002400 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002401
2402 // watchdog service is running/enabled
2403 hostWatchdogTimer["Status"]["State"] = "Enabled";
2404
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002405 const bool* enabled = nullptr;
2406 const std::string* expireAction = nullptr;
2407
2408 const bool success = sdbusplus::unpackPropertiesNoThrow(
2409 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2410 "ExpireAction", expireAction);
2411
2412 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002413 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002414 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002415 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002416 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002417
2418 if (enabled != nullptr)
2419 {
2420 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2421 }
2422
2423 if (expireAction != nullptr)
2424 {
2425 std::string action = dbusToRfWatchdogAction(*expireAction);
2426 if (action.empty())
2427 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002428 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002429 return;
2430 }
2431 hostWatchdogTimer["TimeoutAction"] = action;
2432 }
2433 });
Yong Li51709ff2019-09-30 14:13:04 +08002434}
2435
2436/**
Yong Lic45f0082019-10-10 14:19:01 +08002437 * @brief Sets Host WatchDog Timer properties.
2438 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002439 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002440 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2441 * RF request.
2442 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2443 *
2444 * @return None.
2445 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002446inline void
2447 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2448 const std::optional<bool> wdtEnable,
2449 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002450{
2451 BMCWEB_LOG_DEBUG << "Set host watchdog";
2452
2453 if (wdtTimeOutAction)
2454 {
2455 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2456 // check if TimeOut Action is Valid
2457 if (wdtTimeOutActStr.empty())
2458 {
2459 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2460 << *wdtTimeOutAction;
Ed Tanousac106bf2023-06-07 09:24:59 -07002461 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002462 "TimeoutAction");
2463 return;
2464 }
2465
2466 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002467 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002468 if (ec)
2469 {
2470 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002471 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002472 return;
2473 }
Yong Lic45f0082019-10-10 14:19:01 +08002474 },
2475 "xyz.openbmc_project.Watchdog",
2476 "/xyz/openbmc_project/watchdog/host0",
2477 "org.freedesktop.DBus.Properties", "Set",
2478 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002479 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002480 }
2481
2482 if (wdtEnable)
2483 {
2484 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002485 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002486 if (ec)
2487 {
2488 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002489 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002490 return;
2491 }
Yong Lic45f0082019-10-10 14:19:01 +08002492 },
2493 "xyz.openbmc_project.Watchdog",
2494 "/xyz/openbmc_project/watchdog/host0",
2495 "org.freedesktop.DBus.Properties", "Set",
2496 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002497 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002498 }
2499}
2500
Chris Cain37bbf982021-09-20 10:53:09 -05002501/**
2502 * @brief Parse the Idle Power Saver properties into json
2503 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002504 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002505 * @param[in] properties IPS property data from DBus.
2506 *
2507 * @return true if successful
2508 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002509inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002510 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002511 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002512{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002513 const bool* enabled = nullptr;
2514 const uint8_t* enterUtilizationPercent = nullptr;
2515 const uint64_t* enterDwellTime = nullptr;
2516 const uint8_t* exitUtilizationPercent = nullptr;
2517 const uint64_t* exitDwellTime = nullptr;
2518
2519 const bool success = sdbusplus::unpackPropertiesNoThrow(
2520 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002521 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2522 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2523 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002524
2525 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002526 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002527 return false;
2528 }
2529
2530 if (enabled != nullptr)
2531 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002532 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002533 }
2534
2535 if (enterUtilizationPercent != nullptr)
2536 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002537 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002538 *enterUtilizationPercent;
2539 }
2540
2541 if (enterDwellTime != nullptr)
2542 {
2543 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002544 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002545 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2546 .count();
2547 }
2548
2549 if (exitUtilizationPercent != nullptr)
2550 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002551 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002552 *exitUtilizationPercent;
2553 }
2554
2555 if (exitDwellTime != nullptr)
2556 {
2557 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002558 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002559 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2560 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002561 }
2562
2563 return true;
2564}
2565
2566/**
2567 * @brief Retrieves host watchdog timer properties over DBUS
2568 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002569 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002570 *
2571 * @return None.
2572 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002573inline void
2574 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002575{
2576 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2577
2578 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002579 constexpr std::array<std::string_view, 1> interfaces = {
2580 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2581 dbus::utility::getSubTree(
2582 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002583 [asyncResp](const boost::system::error_code& ec,
2584 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002585 if (ec)
2586 {
2587 BMCWEB_LOG_DEBUG
2588 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2589 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002590 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002591 return;
2592 }
2593 if (subtree.empty())
2594 {
2595 // This is an optional interface so just return
2596 // if there is no instance found
2597 BMCWEB_LOG_DEBUG << "No instances found";
2598 return;
2599 }
2600 if (subtree.size() > 1)
2601 {
2602 // More then one PowerIdlePowerSaver object is not supported and
2603 // is an error
2604 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2605 "Power.IdlePowerSaver objects: "
2606 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002607 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002608 return;
2609 }
2610 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2611 {
2612 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002613 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002614 return;
2615 }
2616 const std::string& path = subtree[0].first;
2617 const std::string& service = subtree[0].second.begin()->first;
2618 if (service.empty())
2619 {
2620 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002621 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002622 return;
2623 }
2624
2625 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002626 sdbusplus::asio::getAllProperties(
2627 *crow::connections::systemBus, service, path,
2628 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002629 [asyncResp](const boost::system::error_code& ec2,
2630 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002631 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002632 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002633 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002634 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002635 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002636 return;
2637 }
2638
Ed Tanousac106bf2023-06-07 09:24:59 -07002639 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002640 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002641 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002642 return;
2643 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002644 });
George Liue99073f2022-12-09 11:06:16 +08002645 });
Chris Cain37bbf982021-09-20 10:53:09 -05002646
2647 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2648}
2649
2650/**
2651 * @brief Sets Idle Power Saver properties.
2652 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002653 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002654 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2655 * RF request.
2656 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2657 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2658 * before entering idle state.
2659 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2660 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2661 * before exiting idle state
2662 *
2663 * @return None.
2664 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002665inline void
2666 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2667 const std::optional<bool> ipsEnable,
2668 const std::optional<uint8_t> ipsEnterUtil,
2669 const std::optional<uint64_t> ipsEnterTime,
2670 const std::optional<uint8_t> ipsExitUtil,
2671 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002672{
2673 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2674
2675 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002676 constexpr std::array<std::string_view, 1> interfaces = {
2677 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2678 dbus::utility::getSubTree(
2679 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002680 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002681 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002682 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002683 if (ec)
2684 {
2685 BMCWEB_LOG_DEBUG
2686 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2687 << ec;
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.empty())
2692 {
2693 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002694 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002695 "IdlePowerSaver");
2696 return;
2697 }
2698 if (subtree.size() > 1)
2699 {
2700 // More then one PowerIdlePowerSaver object is not supported and
2701 // is an error
2702 BMCWEB_LOG_DEBUG
2703 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2704 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002705 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002706 return;
2707 }
2708 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2709 {
2710 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002711 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002712 return;
2713 }
2714 const std::string& path = subtree[0].first;
2715 const std::string& service = subtree[0].second.begin()->first;
2716 if (service.empty())
2717 {
2718 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002719 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002720 return;
2721 }
Chris Cain37bbf982021-09-20 10:53:09 -05002722
Ed Tanous002d39b2022-05-31 08:59:27 -07002723 // Valid Power IdlePowerSaver object found, now set any values that
2724 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002725
Ed Tanous002d39b2022-05-31 08:59:27 -07002726 if (ipsEnable)
2727 {
2728 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002729 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002730 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002731 {
Ed Tanous8a592812022-06-04 09:06:59 -07002732 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002733 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002734 return;
2735 }
2736 },
2737 service, path, "org.freedesktop.DBus.Properties", "Set",
2738 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2739 dbus::utility::DbusVariantType(*ipsEnable));
2740 }
2741 if (ipsEnterUtil)
2742 {
2743 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002744 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002745 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002746 {
Ed Tanous8a592812022-06-04 09:06:59 -07002747 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002748 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002749 return;
2750 }
2751 },
2752 service, path, "org.freedesktop.DBus.Properties", "Set",
2753 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2754 "EnterUtilizationPercent",
2755 dbus::utility::DbusVariantType(*ipsEnterUtil));
2756 }
2757 if (ipsEnterTime)
2758 {
2759 // Convert from seconds into milliseconds for DBus
2760 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2761 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002762 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002763 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002764 {
Ed Tanous8a592812022-06-04 09:06:59 -07002765 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002766 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002767 return;
2768 }
2769 },
2770 service, path, "org.freedesktop.DBus.Properties", "Set",
2771 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2772 "EnterDwellTime",
2773 dbus::utility::DbusVariantType(timeMilliseconds));
2774 }
2775 if (ipsExitUtil)
2776 {
2777 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002778 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002779 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002780 {
Ed Tanous8a592812022-06-04 09:06:59 -07002781 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002782 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002783 return;
2784 }
2785 },
2786 service, path, "org.freedesktop.DBus.Properties", "Set",
2787 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2788 "ExitUtilizationPercent",
2789 dbus::utility::DbusVariantType(*ipsExitUtil));
2790 }
2791 if (ipsExitTime)
2792 {
2793 // Convert from seconds into milliseconds for DBus
2794 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2795 crow::connections::systemBus->async_method_call(
Ed Tanousac106bf2023-06-07 09:24:59 -07002796 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002797 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002798 {
Ed Tanous8a592812022-06-04 09:06:59 -07002799 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002800 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002801 return;
2802 }
2803 },
2804 service, path, "org.freedesktop.DBus.Properties", "Set",
2805 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2806 "ExitDwellTime",
2807 dbus::utility::DbusVariantType(timeMilliseconds));
2808 }
George Liue99073f2022-12-09 11:06:16 +08002809 });
Chris Cain37bbf982021-09-20 10:53:09 -05002810
2811 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2812}
2813
Ed Tanousc1e219d2023-06-07 10:34:33 -07002814inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002815 crow::App& app, const crow::Request& req,
2816 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2817{
2818 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2819 {
2820 return;
2821 }
2822 asyncResp->res.addHeader(
2823 boost::beast::http::field::link,
2824 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2825}
2826
Ed Tanousc1e219d2023-06-07 10:34:33 -07002827inline void handleComputerSystemCollectionGet(
2828 crow::App& app, const crow::Request& req,
2829 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2830{
2831 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2832 {
2833 return;
2834 }
2835
2836 asyncResp->res.addHeader(
2837 boost::beast::http::field::link,
2838 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2839 asyncResp->res.jsonValue["@odata.type"] =
2840 "#ComputerSystemCollection.ComputerSystemCollection";
2841 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2842 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2843
2844 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2845 ifaceArray = nlohmann::json::array();
2846 if constexpr (bmcwebEnableMultiHost)
2847 {
2848 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2849 // Option currently returns no systems. TBD
2850 return;
2851 }
2852 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2853 nlohmann::json::object_t system;
2854 system["@odata.id"] = "/redfish/v1/Systems/system";
2855 ifaceArray.emplace_back(std::move(system));
2856 sdbusplus::asio::getProperty<std::string>(
2857 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2858 "/xyz/openbmc_project/network/hypervisor",
2859 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2860 [asyncResp](const boost::system::error_code& ec2,
2861 const std::string& /*hostName*/) {
2862 if (ec2)
2863 {
2864 return;
2865 }
2866 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2867 if (val == asyncResp->res.jsonValue.end())
2868 {
2869 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2870 return;
2871 }
2872 uint64_t* count = val->get_ptr<uint64_t*>();
2873 if (count == nullptr)
2874 {
2875 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2876 return;
2877 }
2878 *count = *count + 1;
2879 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2880 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2881 nlohmann::json::object_t hypervisor;
2882 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2883 ifaceArray2.emplace_back(std::move(hypervisor));
2884 });
2885}
2886
Yong Lic45f0082019-10-10 14:19:01 +08002887/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002888 * Function transceives data with dbus directly.
2889 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002890inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002891{
Patrick Williams89492a12023-05-10 07:51:34 -05002892 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2893 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2894 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002895 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002896 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002897
2898 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002899 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002900 if (ec)
2901 {
2902 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2903 messages::internalError(asyncResp->res);
2904 return;
2905 }
2906 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002907 },
2908 serviceName, objectPath, interfaceName, method);
2909}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002910
2911/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002912 * Handle error responses from d-bus for system power requests
2913 */
2914inline void handleSystemActionResetError(const boost::system::error_code& ec,
2915 const sdbusplus::message_t& eMsg,
2916 std::string_view resetType,
2917 crow::Response& res)
2918{
2919 if (ec.value() == boost::asio::error::invalid_argument)
2920 {
2921 messages::actionParameterNotSupported(res, resetType, "Reset");
2922 return;
2923 }
2924
2925 if (eMsg.get_error() == nullptr)
2926 {
2927 BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
2928 messages::internalError(res);
2929 return;
2930 }
2931 std::string_view errorMessage = eMsg.get_error()->name;
2932
2933 // If operation failed due to BMC not being in Ready state, tell
2934 // user to retry in a bit
2935 if ((errorMessage ==
2936 std::string_view(
2937 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
2938 (errorMessage ==
2939 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
2940 {
2941 BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
2942 messages::serviceTemporarilyUnavailable(res, "10");
2943 return;
2944 }
2945
2946 BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
2947 << " sdbusplus:" << errorMessage;
2948 messages::internalError(res);
2949}
2950
Ed Tanousc1e219d2023-06-07 10:34:33 -07002951inline void handleComputerSystemResetActionPost(
2952 crow::App& app, const crow::Request& req,
2953 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2954 const std::string& systemName)
2955{
2956 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2957 {
2958 return;
2959 }
2960 if (systemName != "system")
2961 {
2962 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2963 systemName);
2964 return;
2965 }
2966 if constexpr (bmcwebEnableMultiHost)
2967 {
2968 // Option currently returns no systems. TBD
2969 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2970 systemName);
2971 return;
2972 }
2973 std::string resetType;
2974 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2975 {
2976 return;
2977 }
2978
2979 // Get the command and host vs. chassis
2980 std::string command;
2981 bool hostCommand = true;
2982 if ((resetType == "On") || (resetType == "ForceOn"))
2983 {
2984 command = "xyz.openbmc_project.State.Host.Transition.On";
2985 hostCommand = true;
2986 }
2987 else if (resetType == "ForceOff")
2988 {
2989 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2990 hostCommand = false;
2991 }
2992 else if (resetType == "ForceRestart")
2993 {
2994 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2995 hostCommand = true;
2996 }
2997 else if (resetType == "GracefulShutdown")
2998 {
2999 command = "xyz.openbmc_project.State.Host.Transition.Off";
3000 hostCommand = true;
3001 }
3002 else if (resetType == "GracefulRestart")
3003 {
3004 command =
3005 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3006 hostCommand = true;
3007 }
3008 else if (resetType == "PowerCycle")
3009 {
3010 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3011 hostCommand = true;
3012 }
3013 else if (resetType == "Nmi")
3014 {
3015 doNMI(asyncResp);
3016 return;
3017 }
3018 else
3019 {
3020 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3021 return;
3022 }
3023
3024 if (hostCommand)
3025 {
3026 crow::connections::systemBus->async_method_call(
3027 [asyncResp, resetType](const boost::system::error_code& ec,
3028 sdbusplus::message_t& sdbusErrMsg) {
3029 if (ec)
3030 {
3031 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3032 asyncResp->res);
3033
3034 return;
3035 }
3036 messages::success(asyncResp->res);
3037 },
3038 "xyz.openbmc_project.State.Host",
3039 "/xyz/openbmc_project/state/host0",
3040 "org.freedesktop.DBus.Properties", "Set",
3041 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3042 dbus::utility::DbusVariantType{command});
3043 }
3044 else
3045 {
3046 crow::connections::systemBus->async_method_call(
3047 [asyncResp, resetType](const boost::system::error_code& ec,
3048 sdbusplus::message_t& sdbusErrMsg) {
3049 if (ec)
3050 {
3051 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3052 asyncResp->res);
3053 return;
3054 }
3055 messages::success(asyncResp->res);
3056 },
3057 "xyz.openbmc_project.State.Chassis",
3058 "/xyz/openbmc_project/state/chassis0",
3059 "org.freedesktop.DBus.Properties", "Set",
3060 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3061 dbus::utility::DbusVariantType{command});
3062 }
3063}
3064
Ed Tanousc1e219d2023-06-07 10:34:33 -07003065inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003066 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003067 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3068 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003069{
3070 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3071 {
3072 return;
3073 }
3074
3075 asyncResp->res.addHeader(
3076 boost::beast::http::field::link,
3077 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3078}
3079
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003080inline void afterPortRequest(
3081 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3082 const boost::system::error_code& ec,
3083 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3084{
3085 if (ec)
3086 {
3087 messages::internalError(asyncResp->res);
3088 return;
3089 }
3090 for (const auto& data : socketData)
3091 {
3092 const std::string& socketPath = get<0>(data);
3093 const std::string& protocolName = get<1>(data);
3094 bool isProtocolEnabled = get<2>(data);
3095 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3096 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3097 // need to retrieve port number for
3098 // obmc-console-ssh service
3099 if (protocolName == "SSH")
3100 {
3101 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003102 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003103 int portNumber) {
3104 if (ec1)
3105 {
3106 messages::internalError(asyncResp->res);
3107 return;
3108 }
3109 nlohmann::json& dataJson1 =
3110 asyncResp->res.jsonValue["SerialConsole"];
3111 dataJson1[protocolName]["Port"] = portNumber;
3112 });
3113 }
3114 }
3115}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003116
3117inline void
3118 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3119 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3120 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003121{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003122 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3123 {
3124 return;
3125 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003126
Ed Tanousc1e219d2023-06-07 10:34:33 -07003127 if constexpr (bmcwebEnableMultiHost)
3128 {
3129 // Option currently returns no systems. TBD
3130 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3131 systemName);
3132 return;
3133 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003134
Ed Tanousc1e219d2023-06-07 10:34:33 -07003135 if (systemName == "hypervisor")
3136 {
3137 handleHypervisorSystemGet(asyncResp);
3138 return;
3139 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003140
Ed Tanousc1e219d2023-06-07 10:34:33 -07003141 if (systemName != "system")
3142 {
3143 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3144 systemName);
3145 return;
3146 }
3147 asyncResp->res.addHeader(
3148 boost::beast::http::field::link,
3149 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3150 asyncResp->res.jsonValue["@odata.type"] =
3151 "#ComputerSystem.v1_16_0.ComputerSystem";
3152 asyncResp->res.jsonValue["Name"] = "system";
3153 asyncResp->res.jsonValue["Id"] = "system";
3154 asyncResp->res.jsonValue["SystemType"] = "Physical";
3155 asyncResp->res.jsonValue["Description"] = "Computer System";
3156 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3157 if constexpr (bmcwebEnableProcMemStatus)
3158 {
3159 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3160 "Disabled";
3161 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3162 "Disabled";
3163 }
3164 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
3165 uint64_t(0);
3166 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003167
Ed Tanousc1e219d2023-06-07 10:34:33 -07003168 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3169 "/redfish/v1/Systems/system/Processors";
3170 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3171 "/redfish/v1/Systems/system/Memory";
3172 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3173 "/redfish/v1/Systems/system/Storage";
3174 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3175 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003176
Ed Tanousc1e219d2023-06-07 10:34:33 -07003177 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3178 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3179 asyncResp->res
3180 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3181 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003182
Ed Tanousc1e219d2023-06-07 10:34:33 -07003183 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3184 "/redfish/v1/Systems/system/LogServices";
3185 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3186 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003187
Ed Tanousc1e219d2023-06-07 10:34:33 -07003188 nlohmann::json::array_t managedBy;
3189 nlohmann::json& manager = managedBy.emplace_back();
3190 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3191 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3192 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3193 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003194
Ed Tanousc1e219d2023-06-07 10:34:33 -07003195 // Fill in SerialConsole info
3196 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3197 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003198
Ed Tanousc1e219d2023-06-07 10:34:33 -07003199 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3200 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3201 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3202 "Press ~. to exit console";
3203 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3204 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003205
3206#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003207 // Fill in GraphicalConsole info
3208 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3209 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3210 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3211 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003212
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003213#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003214
Ed Tanousc1e219d2023-06-07 10:34:33 -07003215 auto health = std::make_shared<HealthPopulate>(asyncResp);
3216 if constexpr (bmcwebEnableHealthPopulate)
3217 {
3218 constexpr std::array<std::string_view, 4> inventoryForSystems{
3219 "xyz.openbmc_project.Inventory.Item.Dimm",
3220 "xyz.openbmc_project.Inventory.Item.Cpu",
3221 "xyz.openbmc_project.Inventory.Item.Drive",
3222 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003223
Ed Tanousc1e219d2023-06-07 10:34:33 -07003224 dbus::utility::getSubTreePaths(
3225 "/", 0, inventoryForSystems,
3226 [health](const boost::system::error_code& ec,
3227 const std::vector<std::string>& resp) {
3228 if (ec)
3229 {
3230 // no inventory
3231 return;
3232 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003233
Ed Tanousc1e219d2023-06-07 10:34:33 -07003234 health->inventory = resp;
3235 });
3236 health->populate();
3237 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003238
Ed Tanousc1e219d2023-06-07 10:34:33 -07003239 getMainChassisId(asyncResp,
3240 [](const std::string& chassisId,
3241 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3242 nlohmann::json::array_t chassisArray;
3243 nlohmann::json& chassis = chassisArray.emplace_back();
3244 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3245 chassisId);
3246 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3247 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003248
Ed Tanousc1e219d2023-06-07 10:34:33 -07003249 getLocationIndicatorActive(asyncResp);
3250 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3251 getIndicatorLedState(asyncResp);
3252 getComputerSystem(asyncResp, health);
3253 getHostState(asyncResp);
3254 getBootProperties(asyncResp);
3255 getBootProgress(asyncResp);
3256 getBootProgressLastStateTime(asyncResp);
3257 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3258 getHostWatchdogTimer(asyncResp);
3259 getPowerRestorePolicy(asyncResp);
3260 getAutomaticRetryPolicy(asyncResp);
3261 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003262#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003263 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003264#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003265 getTrustedModuleRequiredToBoot(asyncResp);
3266 getPowerMode(asyncResp);
3267 getIdlePowerSaver(asyncResp);
3268}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003269
Ed Tanousc1e219d2023-06-07 10:34:33 -07003270inline void handleComputerSystemPatch(
3271 crow::App& app, const crow::Request& req,
3272 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3273 const std::string& systemName)
3274{
3275 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3276 {
3277 return;
3278 }
3279 if constexpr (bmcwebEnableMultiHost)
3280 {
3281 // Option currently returns no systems. TBD
3282 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3283 systemName);
3284 return;
3285 }
3286 if (systemName != "system")
3287 {
3288 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3289 systemName);
3290 return;
3291 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003292
Ed Tanousc1e219d2023-06-07 10:34:33 -07003293 asyncResp->res.addHeader(
3294 boost::beast::http::field::link,
3295 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003296
Ed Tanousc1e219d2023-06-07 10:34:33 -07003297 std::optional<bool> locationIndicatorActive;
3298 std::optional<std::string> indicatorLed;
3299 std::optional<std::string> assetTag;
3300 std::optional<std::string> powerRestorePolicy;
3301 std::optional<std::string> powerMode;
3302 std::optional<bool> wdtEnable;
3303 std::optional<std::string> wdtTimeOutAction;
3304 std::optional<std::string> bootSource;
3305 std::optional<std::string> bootType;
3306 std::optional<std::string> bootEnable;
3307 std::optional<std::string> bootAutomaticRetry;
3308 std::optional<uint32_t> bootAutomaticRetryAttempts;
3309 std::optional<bool> bootTrustedModuleRequired;
3310 std::optional<bool> ipsEnable;
3311 std::optional<uint8_t> ipsEnterUtil;
3312 std::optional<uint64_t> ipsEnterTime;
3313 std::optional<uint8_t> ipsExitUtil;
3314 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003315
Ed Tanousc1e219d2023-06-07 10:34:33 -07003316 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003317 if (!json_util::readJsonPatch(
3318 req, asyncResp->res,
3319 "IndicatorLED", indicatorLed,
3320 "LocationIndicatorActive", locationIndicatorActive,
3321 "AssetTag", assetTag,
3322 "PowerRestorePolicy", powerRestorePolicy,
3323 "PowerMode", powerMode,
3324 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3325 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3326 "Boot/BootSourceOverrideTarget", bootSource,
3327 "Boot/BootSourceOverrideMode", bootType,
3328 "Boot/BootSourceOverrideEnabled", bootEnable,
3329 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003330 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003331 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3332 "IdlePowerSaver/Enabled", ipsEnable,
3333 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3334 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3335 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3336 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3337 {
3338 return;
3339 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003340 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003341
Ed Tanousc1e219d2023-06-07 10:34:33 -07003342 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003343
Ed Tanousc1e219d2023-06-07 10:34:33 -07003344 if (assetTag)
3345 {
3346 setAssetTag(asyncResp, *assetTag);
3347 }
James Feistb49ac872019-05-21 15:12:01 -07003348
Ed Tanousc1e219d2023-06-07 10:34:33 -07003349 if (wdtEnable || wdtTimeOutAction)
3350 {
3351 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3352 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003353
Ed Tanousc1e219d2023-06-07 10:34:33 -07003354 if (bootSource || bootType || bootEnable)
3355 {
3356 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3357 }
3358 if (bootAutomaticRetry)
3359 {
3360 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3361 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003362
Ed Tanousc1e219d2023-06-07 10:34:33 -07003363 if (bootAutomaticRetryAttempts)
3364 {
3365 setAutomaticRetryAttempts(asyncResp,
3366 bootAutomaticRetryAttempts.value());
3367 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003368
Ed Tanousc1e219d2023-06-07 10:34:33 -07003369 if (bootTrustedModuleRequired)
3370 {
3371 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3372 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003373
Ed Tanousc1e219d2023-06-07 10:34:33 -07003374 if (locationIndicatorActive)
3375 {
3376 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3377 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003378
Ed Tanousc1e219d2023-06-07 10:34:33 -07003379 // TODO (Gunnar): Remove IndicatorLED after enough time has
3380 // passed
3381 if (indicatorLed)
3382 {
3383 setIndicatorLedState(asyncResp, *indicatorLed);
3384 asyncResp->res.addHeader(boost::beast::http::field::warning,
3385 "299 - \"IndicatorLED is deprecated. Use "
3386 "LocationIndicatorActive instead.\"");
3387 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003388
Ed Tanousc1e219d2023-06-07 10:34:33 -07003389 if (powerRestorePolicy)
3390 {
3391 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3392 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003393
Ed Tanousc1e219d2023-06-07 10:34:33 -07003394 if (powerMode)
3395 {
3396 setPowerMode(asyncResp, *powerMode);
3397 }
Chris Cain37bbf982021-09-20 10:53:09 -05003398
Ed Tanousc1e219d2023-06-07 10:34:33 -07003399 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3400 {
3401 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3402 ipsExitUtil, ipsExitTime);
3403 }
3404}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303405
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003406inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003407 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003408 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003409 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003410{
3411 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3412 {
3413 return;
3414 }
3415 asyncResp->res.addHeader(
3416 boost::beast::http::field::link,
3417 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3418}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003419inline void handleSystemCollectionResetActionGet(
3420 crow::App& app, const crow::Request& req,
3421 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3422 const std::string& systemName)
3423{
3424 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3425 {
3426 return;
3427 }
3428 if constexpr (bmcwebEnableMultiHost)
3429 {
3430 // Option currently returns no systems. TBD
3431 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3432 systemName);
3433 return;
3434 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003435
Ed Tanousc1e219d2023-06-07 10:34:33 -07003436 if (systemName == "hypervisor")
3437 {
3438 handleHypervisorResetActionGet(asyncResp);
3439 return;
3440 }
3441
3442 if (systemName != "system")
3443 {
3444 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3445 systemName);
3446 return;
3447 }
3448
3449 asyncResp->res.addHeader(
3450 boost::beast::http::field::link,
3451 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3452
3453 asyncResp->res.jsonValue["@odata.id"] =
3454 "/redfish/v1/Systems/system/ResetActionInfo";
3455 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3456 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3457 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3458
3459 nlohmann::json::array_t parameters;
3460 nlohmann::json::object_t parameter;
3461
3462 parameter["Name"] = "ResetType";
3463 parameter["Required"] = true;
3464 parameter["DataType"] = "String";
3465 nlohmann::json::array_t allowableValues;
3466 allowableValues.emplace_back("On");
3467 allowableValues.emplace_back("ForceOff");
3468 allowableValues.emplace_back("ForceOn");
3469 allowableValues.emplace_back("ForceRestart");
3470 allowableValues.emplace_back("GracefulRestart");
3471 allowableValues.emplace_back("GracefulShutdown");
3472 allowableValues.emplace_back("PowerCycle");
3473 allowableValues.emplace_back("Nmi");
3474 parameter["AllowableValues"] = std::move(allowableValues);
3475 parameters.emplace_back(std::move(parameter));
3476
3477 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3478}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303479/**
3480 * SystemResetActionInfo derived class for delivering Computer Systems
3481 * ResetType AllowableValues using ResetInfo schema.
3482 */
Ed Tanous100afe52023-06-07 13:30:46 -07003483inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303484{
Ed Tanous100afe52023-06-07 13:30:46 -07003485 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3486 .privileges(redfish::privileges::headComputerSystemCollection)
3487 .methods(boost::beast::http::verb::head)(
3488 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3489
3490 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3491 .privileges(redfish::privileges::getComputerSystemCollection)
3492 .methods(boost::beast::http::verb::get)(
3493 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3494
3495 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3496 .privileges(redfish::privileges::headComputerSystem)
3497 .methods(boost::beast::http::verb::head)(
3498 std::bind_front(handleComputerSystemHead, std::ref(app)));
3499
3500 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3501 .privileges(redfish::privileges::getComputerSystem)
3502 .methods(boost::beast::http::verb::get)(
3503 std::bind_front(handleComputerSystemGet, std::ref(app)));
3504
3505 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3506 .privileges(redfish::privileges::patchComputerSystem)
3507 .methods(boost::beast::http::verb::patch)(
3508 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3509
3510 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3511 .privileges(redfish::privileges::postComputerSystem)
3512 .methods(boost::beast::http::verb::post)(std::bind_front(
3513 handleComputerSystemResetActionPost, std::ref(app)));
3514
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003515 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003516 .privileges(redfish::privileges::headActionInfo)
3517 .methods(boost::beast::http::verb::head)(std::bind_front(
3518 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003519 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003520 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003521 .methods(boost::beast::http::verb::get)(std::bind_front(
3522 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003523}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003524} // namespace redfish