blob: 69ef4908d10504529e667d0754ae360f1a3c5983 [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"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500300 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500301 if (preValue == nullptr)
302 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700303 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500304 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500305 }
306 else
307 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700308 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500309 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
310 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500311 }
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500312 if constexpr (bmcwebEnableProcMemStatus)
313 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700314 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500315 "Enabled";
316 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500317 }
318}
319
320/*
321 * @brief Get getMemorySummary fields
322 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700323 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500324 * @param[in] service dbus service for memory Information
325 * @param[in] path dbus path for memory
326 *
327 * @return None.
328 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700329inline void
330 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500332{
333 sdbusplus::asio::getAllProperties(
334 *crow::connections::systemBus, service, path,
335 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700336 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500337 path](const boost::system::error_code& ec2,
338 const dbus::utility::DBusPropertiesMap& properties) {
339 if (ec2)
340 {
341 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -0700342 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500343 return;
344 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700345 processMemoryProperties(asyncResp, service, path, properties);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500346 });
347}
348
349/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700350 * @brief Retrieves computer system properties over dbus
351 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700352 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500353 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700354 *
355 * @return None.
356 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700357inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700358 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700359 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700360{
Ed Tanous6c34de42018-08-29 13:37:36 -0700361 BMCWEB_LOG_DEBUG << "Get available system components.";
George Liue99073f2022-12-09 11:06:16 +0800362 constexpr std::array<std::string_view, 5> interfaces = {
363 "xyz.openbmc_project.Inventory.Decorator.Asset",
364 "xyz.openbmc_project.Inventory.Item.Cpu",
365 "xyz.openbmc_project.Inventory.Item.Dimm",
366 "xyz.openbmc_project.Inventory.Item.System",
367 "xyz.openbmc_project.Common.UUID",
368 };
369 dbus::utility::getSubTree(
370 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700371 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +0800372 systemHealth](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800373 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700374 if (ec)
375 {
376 BMCWEB_LOG_DEBUG << "DBUS response error";
Ed Tanousac106bf2023-06-07 09:24:59 -0700377 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700378 return;
379 }
380 // Iterate over all retrieved ObjectPaths.
381 for (const std::pair<
382 std::string,
383 std::vector<std::pair<std::string, std::vector<std::string>>>>&
384 object : subtree)
385 {
386 const std::string& path = object.first;
387 BMCWEB_LOG_DEBUG << "Got path: " << path;
388 const std::vector<std::pair<std::string, std::vector<std::string>>>&
389 connectionNames = object.second;
390 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700391 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700392 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700393 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700394
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500395 std::shared_ptr<HealthPopulate> memoryHealth = nullptr;
396 std::shared_ptr<HealthPopulate> cpuHealth = nullptr;
Ed Tanous002d39b2022-05-31 08:59:27 -0700397
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500398 if constexpr (bmcwebEnableProcMemStatus)
Willy Tu13451e32023-05-24 16:08:18 -0700399 {
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500400 memoryHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700401 asyncResp, "/MemorySummary/Status"_json_pointer);
Willy Tu13451e32023-05-24 16:08:18 -0700402 systemHealth->children.emplace_back(memoryHealth);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500403
404 if constexpr (bmcwebEnableHealthPopulate)
405 {
406 cpuHealth = std::make_shared<HealthPopulate>(
Ed Tanousac106bf2023-06-07 09:24:59 -0700407 asyncResp, "/ProcessorSummary/Status"_json_pointer);
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500408
409 systemHealth->children.emplace_back(cpuHealth);
410 }
Willy Tu13451e32023-05-24 16:08:18 -0700411 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700412
413 // This is not system, so check if it's cpu, dimm, UUID or
414 // BiosVer
415 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700416 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700417 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700418 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700419 if (interfaceName ==
420 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700421 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700422 BMCWEB_LOG_DEBUG
423 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500424
Ed Tanousac106bf2023-06-07 09:24:59 -0700425 getMemorySummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700426
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500427 if constexpr (bmcwebEnableProcMemStatus)
428 {
429 memoryHealth->inventory.emplace_back(path);
430 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700431 }
432 else if (interfaceName ==
433 "xyz.openbmc_project.Inventory.Item.Cpu")
434 {
435 BMCWEB_LOG_DEBUG
436 << "Found Cpu, now get its properties.";
437
Ed Tanousac106bf2023-06-07 09:24:59 -0700438 getProcessorSummary(asyncResp, connection.first, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700439
Ninad Palsule5fd0aaf2023-04-20 15:11:21 -0500440 if constexpr (bmcwebEnableProcMemStatus)
441 {
442 cpuHealth->inventory.emplace_back(path);
443 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700444 }
445 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
446 {
447 BMCWEB_LOG_DEBUG
448 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200449
450 sdbusplus::asio::getAllProperties(
451 *crow::connections::systemBus, connection.first,
452 path, "xyz.openbmc_project.Common.UUID",
Ed Tanousac106bf2023-06-07 09:24:59 -0700453 [asyncResp](const boost::system::error_code& ec3,
454 const dbus::utility::DBusPropertiesMap&
455 properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700456 if (ec3)
457 {
458 BMCWEB_LOG_DEBUG << "DBUS response error "
459 << ec3;
Ed Tanousac106bf2023-06-07 09:24:59 -0700460 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700461 return;
462 }
463 BMCWEB_LOG_DEBUG << "Got " << properties.size()
464 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700465
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200466 const std::string* uUID = nullptr;
467
468 const bool success =
469 sdbusplus::unpackPropertiesNoThrow(
470 dbus_utils::UnpackErrorPrinter(),
471 properties, "UUID", uUID);
472
473 if (!success)
474 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700475 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200476 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700477 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200478
479 if (uUID != nullptr)
480 {
481 std::string valueStr = *uUID;
482 if (valueStr.size() == 32)
483 {
484 valueStr.insert(8, 1, '-');
485 valueStr.insert(13, 1, '-');
486 valueStr.insert(18, 1, '-');
487 valueStr.insert(23, 1, '-');
488 }
489 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
Ed Tanousac106bf2023-06-07 09:24:59 -0700490 asyncResp->res.jsonValue["UUID"] = valueStr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200491 }
492 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700493 }
494 else if (interfaceName ==
495 "xyz.openbmc_project.Inventory.Item.System")
496 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200497 sdbusplus::asio::getAllProperties(
498 *crow::connections::systemBus, connection.first,
499 path,
500 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanousac106bf2023-06-07 09:24:59 -0700501 [asyncResp](const boost::system::error_code& ec2,
502 const dbus::utility::DBusPropertiesMap&
503 propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700504 if (ec2)
505 {
506 // doesn't have to include this
507 // interface
508 return;
509 }
510 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
511 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200512
513 const std::string* partNumber = nullptr;
514 const std::string* serialNumber = nullptr;
515 const std::string* manufacturer = nullptr;
516 const std::string* model = nullptr;
517 const std::string* subModel = nullptr;
518
519 const bool success =
520 sdbusplus::unpackPropertiesNoThrow(
521 dbus_utils::UnpackErrorPrinter(),
522 propertiesList, "PartNumber", partNumber,
523 "SerialNumber", serialNumber,
524 "Manufacturer", manufacturer, "Model",
525 model, "SubModel", subModel);
526
527 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700528 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700529 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200530 return;
531 }
532
533 if (partNumber != nullptr)
534 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700535 asyncResp->res.jsonValue["PartNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200536 *partNumber;
537 }
538
539 if (serialNumber != nullptr)
540 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700541 asyncResp->res.jsonValue["SerialNumber"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200542 *serialNumber;
543 }
544
545 if (manufacturer != nullptr)
546 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700547 asyncResp->res.jsonValue["Manufacturer"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200548 *manufacturer;
549 }
550
551 if (model != nullptr)
552 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700553 asyncResp->res.jsonValue["Model"] = *model;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200554 }
555
556 if (subModel != nullptr)
557 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700558 asyncResp->res.jsonValue["SubModel"] =
559 *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700560 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500561
Ed Tanous002d39b2022-05-31 08:59:27 -0700562 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700563 sw_util::populateSoftwareInformation(
Ed Tanousac106bf2023-06-07 09:24:59 -0700564 asyncResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700565 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200566 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700567
Ed Tanous002d39b2022-05-31 08:59:27 -0700568 sdbusplus::asio::getProperty<std::string>(
569 *crow::connections::systemBus, connection.first,
570 path,
571 "xyz.openbmc_project.Inventory.Decorator."
572 "AssetTag",
573 "AssetTag",
Ed Tanousac106bf2023-06-07 09:24:59 -0700574 [asyncResp](const boost::system::error_code& ec2,
575 const std::string& value) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700576 if (ec2)
577 {
578 // doesn't have to include this
579 // interface
580 return;
581 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700582
Ed Tanousac106bf2023-06-07 09:24:59 -0700583 asyncResp->res.jsonValue["AssetTag"] = value;
Ed Tanous002d39b2022-05-31 08:59:27 -0700584 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700585 }
586 }
587 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700588 }
Ed Tanous66173382018-08-15 18:20:59 -0700589 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700590}
591
592/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700593 * @brief Retrieves host state properties over dbus
594 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700595 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700596 *
597 * @return None.
598 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700599inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700600{
601 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700602 sdbusplus::asio::getProperty<std::string>(
603 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
604 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
605 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700606 [asyncResp](const boost::system::error_code& ec,
607 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700608 if (ec)
609 {
610 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700611 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700612 // Service not available, no error, just don't return
613 // host state info
614 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700615 return;
616 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700617 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -0700618 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700619 return;
620 }
Ed Tanous66173382018-08-15 18:20:59 -0700621
Ed Tanous002d39b2022-05-31 08:59:27 -0700622 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
623 // Verify Host State
624 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
625 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700626 asyncResp->res.jsonValue["PowerState"] = "On";
627 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700628 }
629 else if (hostState ==
630 "xyz.openbmc_project.State.Host.HostState.Quiesced")
631 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700632 asyncResp->res.jsonValue["PowerState"] = "On";
633 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700634 }
635 else if (hostState ==
636 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
637 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700638 asyncResp->res.jsonValue["PowerState"] = "On";
639 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700640 }
641 else if (
642 hostState ==
643 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
644 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700645 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
646 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700647 }
648 else if (hostState ==
649 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
650 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700651 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
652 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700653 }
654 else
655 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700656 asyncResp->res.jsonValue["PowerState"] = "Off";
657 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700658 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700659 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700660}
661
662/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500663 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530664 *
665 * @param[in] dbusSource The boot source in DBUS speak.
666 *
667 * @return Returns as a string, the boot source in Redfish terms. If translation
668 * cannot be done, returns an empty string.
669 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000670inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530671{
672 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
673 {
674 return "None";
675 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700676 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530677 {
678 return "Hdd";
679 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700680 if (dbusSource ==
681 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682 {
683 return "Cd";
684 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700685 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530686 {
687 return "Pxe";
688 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700689 if (dbusSource ==
690 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700691 {
692 return "Usb";
693 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700694 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530695}
696
697/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300698 * @brief Translates boot type DBUS property value to redfish.
699 *
700 * @param[in] dbusType The boot type in DBUS speak.
701 *
702 * @return Returns as a string, the boot type in Redfish terms. If translation
703 * cannot be done, returns an empty string.
704 */
705inline std::string dbusToRfBootType(const std::string& dbusType)
706{
707 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
708 {
709 return "Legacy";
710 }
711 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
712 {
713 return "UEFI";
714 }
715 return "";
716}
717
718/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500719 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530720 *
721 * @param[in] dbusMode The boot mode in DBUS speak.
722 *
723 * @return Returns as a string, the boot mode in Redfish terms. If translation
724 * cannot be done, returns an empty string.
725 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000726inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530727{
728 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
729 {
730 return "None";
731 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700732 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530733 {
734 return "Diags";
735 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700736 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530737 {
738 return "BiosSetup";
739 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700740 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530741}
742
743/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600744 * @brief Translates boot progress DBUS property value to redfish.
745 *
746 * @param[in] dbusBootProgress The boot progress in DBUS speak.
747 *
748 * @return Returns as a string, the boot progress in Redfish terms. If
749 * translation cannot be done, returns "None".
750 */
751inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
752{
753 // Now convert the D-Bus BootProgress to the appropriate Redfish
754 // enum
755 std::string rfBpLastState = "None";
756 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
757 "ProgressStages.Unspecified")
758 {
759 rfBpLastState = "None";
760 }
761 else if (dbusBootProgress ==
762 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
763 "PrimaryProcInit")
764 {
765 rfBpLastState = "PrimaryProcessorInitializationStarted";
766 }
767 else if (dbusBootProgress ==
768 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
769 "BusInit")
770 {
771 rfBpLastState = "BusInitializationStarted";
772 }
773 else if (dbusBootProgress ==
774 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
775 "MemoryInit")
776 {
777 rfBpLastState = "MemoryInitializationStarted";
778 }
779 else if (dbusBootProgress ==
780 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
781 "SecondaryProcInit")
782 {
783 rfBpLastState = "SecondaryProcessorInitializationStarted";
784 }
785 else if (dbusBootProgress ==
786 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
787 "PCIInit")
788 {
789 rfBpLastState = "PCIResourceConfigStarted";
790 }
791 else if (dbusBootProgress ==
792 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
793 "SystemSetup")
794 {
795 rfBpLastState = "SetupEntered";
796 }
797 else if (dbusBootProgress ==
798 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
799 "SystemInitComplete")
800 {
801 rfBpLastState = "SystemHardwareInitializationComplete";
802 }
803 else if (dbusBootProgress ==
804 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
805 "OSStart")
806 {
807 rfBpLastState = "OSBootStarted";
808 }
809 else if (dbusBootProgress ==
810 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
811 "OSRunning")
812 {
813 rfBpLastState = "OSRunning";
814 }
815 else
816 {
817 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
818 << dbusBootProgress;
819 // Just return the default
820 }
821 return rfBpLastState;
822}
823
824/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500825 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530826 *
827 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700828 * @param[out] bootSource The DBus source
829 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530830 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700831 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530832 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700833inline int
834 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
835 const std::string& rfSource, std::string& bootSource,
836 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530837{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300838 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
839 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700840
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530841 if (rfSource == "None")
842 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700843 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530844 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700845 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530846 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700847 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
848 }
849 else if (rfSource == "Hdd")
850 {
851 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
852 }
853 else if (rfSource == "Diags")
854 {
855 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
856 }
857 else if (rfSource == "Cd")
858 {
859 bootSource =
860 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
861 }
862 else if (rfSource == "BiosSetup")
863 {
864 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530865 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700866 else if (rfSource == "Usb")
867 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700868 bootSource =
869 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700870 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530871 else
872 {
George Liu0fda0f12021-11-16 10:06:17 +0800873 BMCWEB_LOG_DEBUG
874 << "Invalid property value for BootSourceOverrideTarget: "
875 << bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -0700876 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700877 "BootSourceTargetOverride");
878 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530879 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700880 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530881}
Ali Ahmed19817712021-06-29 17:01:52 -0500882
Andrew Geissler978b8802020-11-19 13:36:40 -0600883/**
884 * @brief Retrieves boot progress of the system
885 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700886 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600887 *
888 * @return None.
889 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700890inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600891{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700892 sdbusplus::asio::getProperty<std::string>(
893 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
894 "/xyz/openbmc_project/state/host0",
895 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700896 [asyncResp](const boost::system::error_code& ec,
897 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700898 if (ec)
899 {
900 // BootProgress is an optional object so just do nothing if
901 // not found
902 return;
903 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600904
Ed Tanous002d39b2022-05-31 08:59:27 -0700905 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600906
Ed Tanousac106bf2023-06-07 09:24:59 -0700907 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700908 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700909 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600910}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530911
912/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000913 * @brief Retrieves boot progress Last Update of the system
914 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700915 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000916 *
917 * @return None.
918 */
919inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700920 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000921{
922 sdbusplus::asio::getProperty<uint64_t>(
923 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
924 "/xyz/openbmc_project/state/host0",
925 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700926 [asyncResp](const boost::system::error_code& ec,
927 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000928 if (ec)
929 {
930 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
931 return;
932 }
933
934 // BootProgressLastUpdate is the last time the BootProgress property
935 // was updated. The time is the Epoch time, number of microseconds
936 // since 1 Jan 1970 00::00::00 UTC."
937 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
938 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
939
940 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700941 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000942 redfish::time_utils::getDateTimeUintUs(lastStateTime);
943 });
944}
945
946/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300947 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300948 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700949 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300950 *
951 * @return None.
952 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300953
Ed Tanousac106bf2023-06-07 09:24:59 -0700954inline void
955 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300956{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700957 sdbusplus::asio::getProperty<std::string>(
958 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
959 "/xyz/openbmc_project/control/host0/boot",
960 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700961 [asyncResp](const boost::system::error_code& ec,
962 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700963 if (ec)
964 {
965 // not an error, don't have to have the interface
966 return;
967 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300968
Ed Tanous002d39b2022-05-31 08:59:27 -0700969 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300970
Ed Tanousac106bf2023-06-07 09:24:59 -0700971 asyncResp->res
972 .jsonValue["Boot"]
973 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700974 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300975
Ed Tanous002d39b2022-05-31 08:59:27 -0700976 auto rfType = dbusToRfBootType(bootType);
977 if (rfType.empty())
978 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700979 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700980 return;
981 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300982
Ed Tanousac106bf2023-06-07 09:24:59 -0700983 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700984 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300985}
986
987/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300988 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530989 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700990 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530991 *
992 * @return None.
993 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300994
Ed Tanousac106bf2023-06-07 09:24:59 -0700995inline void
996 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530997{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700998 sdbusplus::asio::getProperty<std::string>(
999 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1000 "/xyz/openbmc_project/control/host0/boot",
1001 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07001002 [asyncResp](const boost::system::error_code& ec,
1003 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001004 if (ec)
1005 {
1006 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001007 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001008 return;
1009 }
1010
1011 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
1012
Ed Tanousac106bf2023-06-07 09:24:59 -07001013 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -07001014 .jsonValue["Boot"]
1015 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
1016 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
1017
1018 if (bootModeStr !=
1019 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
1020 {
1021 auto rfMode = dbusToRfBootMode(bootModeStr);
1022 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301023 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001024 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001025 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301026 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001027 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001028 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301029}
1030
1031/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001032 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301033 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001034 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301035 *
1036 * @return None.
1037 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001038
1039inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001040 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301041{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001042 sdbusplus::asio::getProperty<std::string>(
1043 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1044 "/xyz/openbmc_project/control/host0/boot",
1045 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -07001046 [asyncResp](const boost::system::error_code& ec,
1047 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001048 if (ec)
1049 {
1050 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001051 if (ec.value() == boost::asio::error::host_unreachable)
1052 {
1053 return;
1054 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001055 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001056 return;
1057 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301058
Ed Tanous002d39b2022-05-31 08:59:27 -07001059 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301060
Ed Tanous002d39b2022-05-31 08:59:27 -07001061 auto rfSource = dbusToRfBootSource(bootSourceStr);
1062 if (!rfSource.empty())
1063 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001064 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1065 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -07001066 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001067
Ed Tanous002d39b2022-05-31 08:59:27 -07001068 // Get BootMode as BootSourceOverrideTarget is constructed
1069 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001070 getBootOverrideMode(asyncResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001071 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301072}
1073
1074/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001075 * @brief This functions abstracts all the logic behind getting a
1076 * "BootSourceOverrideEnabled" property from an overall boot override enable
1077 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301078 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001079 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301080 *
1081 * @return None.
1082 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301083
Ed Tanousac106bf2023-06-07 09:24:59 -07001084inline void processBootOverrideEnable(
1085 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1086 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001087{
1088 if (!bootOverrideEnableSetting)
1089 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001090 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1091 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001092 return;
1093 }
1094
1095 // If boot source override is enabled, we need to check 'one_time'
1096 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001097 sdbusplus::asio::getProperty<bool>(
1098 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1099 "/xyz/openbmc_project/control/host0/boot/one_time",
1100 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001101 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001102 if (ec)
1103 {
1104 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001105 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001106 return;
1107 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301108
Ed Tanous002d39b2022-05-31 08:59:27 -07001109 if (oneTimeSetting)
1110 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001111 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1112 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001113 }
1114 else
1115 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001116 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001117 "Continuous";
1118 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001119 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301120}
1121
1122/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001123 * @brief Retrieves boot override enable over DBUS
1124 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001125 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001126 *
1127 * @return None.
1128 */
1129
1130inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001131 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001132{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001133 sdbusplus::asio::getProperty<bool>(
1134 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1135 "/xyz/openbmc_project/control/host0/boot",
1136 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001137 [asyncResp](const boost::system::error_code& ec,
1138 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001139 if (ec)
1140 {
1141 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001142 if (ec.value() == boost::asio::error::host_unreachable)
1143 {
1144 return;
1145 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001146 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001147 return;
1148 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001149
Ed Tanousac106bf2023-06-07 09:24:59 -07001150 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001151 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001152}
1153
1154/**
1155 * @brief Retrieves boot source override properties
1156 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001157 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001158 *
1159 * @return None.
1160 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001161inline void
1162 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001163{
1164 BMCWEB_LOG_DEBUG << "Get boot information.";
1165
Ed Tanousac106bf2023-06-07 09:24:59 -07001166 getBootOverrideSource(asyncResp);
1167 getBootOverrideType(asyncResp);
1168 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001169}
1170
1171/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001172 * @brief Retrieves the Last Reset Time
1173 *
1174 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1175 * and power off. Even though this is the "system" Redfish object look at the
1176 * chassis D-Bus interface for the LastStateChangeTime since this has the
1177 * last power operation time.
1178 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001179 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001180 *
1181 * @return None.
1182 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001183inline void
1184 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001185{
1186 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1187
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001188 sdbusplus::asio::getProperty<uint64_t>(
1189 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1190 "/xyz/openbmc_project/state/chassis0",
1191 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001192 [asyncResp](const boost::system::error_code& ec,
1193 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001194 if (ec)
1195 {
1196 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1197 return;
1198 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001199
Ed Tanous002d39b2022-05-31 08:59:27 -07001200 // LastStateChangeTime is epoch time, in milliseconds
1201 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1202 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001203
Ed Tanous002d39b2022-05-31 08:59:27 -07001204 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001205 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001206 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001207 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001208}
1209
1210/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001211 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1212 *
1213 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1214 * corresponding property "AttemptsLeft" that keeps track of the amount of
1215 * automatic retry attempts left are hosted in phosphor-state-manager through
1216 * dbus.
1217 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001218 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001219 *
1220 * @return None.
1221 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001222inline void getAutomaticRebootAttempts(
1223 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001224{
1225 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1226
1227 sdbusplus::asio::getAllProperties(
1228 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1229 "/xyz/openbmc_project/state/host0",
1230 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001231 [asyncResp{asyncResp}](
1232 const boost::system::error_code& ec,
1233 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001234 if (ec)
1235 {
1236 if (ec.value() != EBADR)
1237 {
1238 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001239 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001240 }
1241 return;
1242 }
1243
1244 const uint32_t* attemptsLeft = nullptr;
1245 const uint32_t* retryAttempts = nullptr;
1246
1247 const bool success = sdbusplus::unpackPropertiesNoThrow(
1248 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1249 attemptsLeft, "RetryAttempts", retryAttempts);
1250
1251 if (!success)
1252 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001253 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001254 return;
1255 }
1256
1257 if (attemptsLeft != nullptr)
1258 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001259 asyncResp->res
1260 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001261 *attemptsLeft;
1262 }
1263
1264 if (retryAttempts != nullptr)
1265 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001266 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001267 *retryAttempts;
1268 }
1269 });
1270}
1271
1272/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001273 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1274 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001275 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001276 *
1277 * @return None.
1278 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001279inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001280 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001281{
1282 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1283
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001284 sdbusplus::asio::getProperty<bool>(
1285 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1286 "/xyz/openbmc_project/control/host0/auto_reboot",
1287 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001288 [asyncResp](const boost::system::error_code& ec,
1289 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001290 if (ec)
1291 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001292 if (ec.value() != EBADR)
1293 {
1294 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001295 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001296 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001297 return;
1298 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001299
Ed Tanous002d39b2022-05-31 08:59:27 -07001300 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1301 if (autoRebootEnabled)
1302 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001303 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001304 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001305 }
1306 else
1307 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001308 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1309 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001310 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001311 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001312
Ed Tanous002d39b2022-05-31 08:59:27 -07001313 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1314 // and RetryAttempts. OpenBMC only supports Disabled and
1315 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001316 asyncResp->res
1317 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1318 {"Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001319 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001320}
1321
1322/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001323 * @brief Sets RetryAttempts
1324 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001325 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001326 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1327 *
1328 *@return None.
1329 */
1330
Ed Tanousac106bf2023-06-07 09:24:59 -07001331inline void setAutomaticRetryAttempts(
1332 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1333 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001334{
1335 BMCWEB_LOG_DEBUG << "Set Automatic Retry Attempts.";
George Liu9ae226f2023-06-21 17:56:46 +08001336 sdbusplus::asio::setProperty(
1337 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1338 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001339 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001340 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
1341 if (ec)
1342 {
1343 BMCWEB_LOG_ERROR
1344 << "DBUS response error: Set setAutomaticRetryAttempts"
1345 << ec;
1346 messages::internalError(asyncResp->res);
1347 return;
1348 }
1349 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001350}
1351
Ed Tanous8d69c662023-06-21 10:29:06 -07001352inline computer_system::PowerRestorePolicyTypes
1353 redfishPowerRestorePolicyFromDbus(std::string_view value)
1354{
1355 if (value ==
1356 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1357 {
1358 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1359 }
1360 if (value ==
1361 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1362 {
1363 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1364 }
1365 if (value ==
1366 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysRestore")
1367 {
1368 return computer_system::PowerRestorePolicyTypes::LastState;
1369 }
1370 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1371 {
1372 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1373 }
1374 return computer_system::PowerRestorePolicyTypes::Invalid;
1375}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001376/**
George Liuc6a620f2020-04-10 17:18:11 +08001377 * @brief Retrieves power restore policy over DBUS.
1378 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001379 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001380 *
1381 * @return None.
1382 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001383inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001384 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001385{
1386 BMCWEB_LOG_DEBUG << "Get power restore policy";
1387
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001388 sdbusplus::asio::getProperty<std::string>(
1389 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1390 "/xyz/openbmc_project/control/host0/power_restore_policy",
1391 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001392 [asyncResp](const boost::system::error_code& ec,
1393 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001394 if (ec)
1395 {
1396 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1397 return;
1398 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001399 computer_system::PowerRestorePolicyTypes restore =
1400 redfishPowerRestorePolicyFromDbus(policy);
1401 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001402 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001403 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001404 return;
1405 }
George Liuc6a620f2020-04-10 17:18:11 +08001406
Ed Tanous8d69c662023-06-21 10:29:06 -07001407 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001408 });
George Liuc6a620f2020-04-10 17:18:11 +08001409}
1410
1411/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001412 * @brief Stop Boot On Fault over DBUS.
1413 *
1414 * @param[in] asyncResp Shared pointer for generating response message.
1415 *
1416 * @return None.
1417 */
1418inline void
1419 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1420{
1421 BMCWEB_LOG_DEBUG << "Get Stop Boot On Fault";
1422
1423 sdbusplus::asio::getProperty<bool>(
1424 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1425 "/xyz/openbmc_project/logging/settings",
1426 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1427 [asyncResp](const boost::system::error_code& ec, bool value) {
1428 if (ec)
1429 {
1430 if (ec.value() != EBADR)
1431 {
1432 messages::internalError(asyncResp->res);
1433 }
1434 return;
1435 }
1436
1437 if (value)
1438 {
1439 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1440 }
1441 else
1442 {
1443 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1444 }
1445 });
1446}
1447
1448/**
Ali Ahmed19817712021-06-29 17:01:52 -05001449 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1450 * TPM is required for booting the host.
1451 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001452 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001453 *
1454 * @return None.
1455 */
1456inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001457 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001458{
1459 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001460 constexpr std::array<std::string_view, 1> interfaces = {
1461 "xyz.openbmc_project.Control.TPM.Policy"};
1462 dbus::utility::getSubTree(
1463 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001464 [asyncResp](const boost::system::error_code& ec,
1465 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001466 if (ec)
1467 {
1468 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1469 << ec;
1470 // This is an optional D-Bus object so just return if
1471 // error occurs
1472 return;
1473 }
1474 if (subtree.empty())
1475 {
1476 // As noted above, this is an optional interface so just return
1477 // if there is no instance found
1478 return;
1479 }
1480
1481 /* When there is more than one TPMEnable object... */
1482 if (subtree.size() > 1)
1483 {
1484 BMCWEB_LOG_DEBUG
1485 << "DBUS response has more than 1 TPM Enable object:"
1486 << subtree.size();
1487 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001488 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001489 return;
1490 }
1491
1492 // Make sure the Dbus response map has a service and objectPath
1493 // field
1494 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1495 {
1496 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001497 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001498 return;
1499 }
1500
1501 const std::string& path = subtree[0].first;
1502 const std::string& serv = subtree[0].second.begin()->first;
1503
1504 // Valid TPM Enable object found, now reading the current value
1505 sdbusplus::asio::getProperty<bool>(
1506 *crow::connections::systemBus, serv, path,
1507 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001508 [asyncResp](const boost::system::error_code& ec2,
1509 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001510 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001511 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001512 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001513 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001514 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001515 return;
1516 }
1517
Ed Tanous002d39b2022-05-31 08:59:27 -07001518 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001519 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001520 asyncResp->res
1521 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001522 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001523 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001524 else
1525 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001526 asyncResp->res
1527 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001528 "Disabled";
1529 }
1530 });
George Liue99073f2022-12-09 11:06:16 +08001531 });
Ali Ahmed19817712021-06-29 17:01:52 -05001532}
1533
1534/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001535 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1536 * TPM is required for booting the host.
1537 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001538 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001539 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1540 *
1541 * @return None.
1542 */
1543inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001544 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001545{
1546 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001547 constexpr std::array<std::string_view, 1> interfaces = {
1548 "xyz.openbmc_project.Control.TPM.Policy"};
1549 dbus::utility::getSubTree(
1550 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001551 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001552 tpmRequired](const boost::system::error_code& ec,
1553 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001554 if (ec)
1555 {
1556 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1557 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001558 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001559 return;
1560 }
1561 if (subtree.empty())
1562 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001563 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001564 "TrustedModuleRequiredToBoot");
1565 return;
1566 }
1567
1568 /* When there is more than one TPMEnable object... */
1569 if (subtree.size() > 1)
1570 {
1571 BMCWEB_LOG_DEBUG
1572 << "DBUS response has more than 1 TPM Enable object:"
1573 << subtree.size();
1574 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001575 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001576 return;
1577 }
1578
1579 // Make sure the Dbus response map has a service and objectPath
1580 // field
1581 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1582 {
1583 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001584 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001585 return;
1586 }
1587
1588 const std::string& path = subtree[0].first;
1589 const std::string& serv = subtree[0].second.begin()->first;
1590
1591 if (serv.empty())
1592 {
1593 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001594 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001595 return;
1596 }
1597
1598 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001599 sdbusplus::asio::setProperty(
1600 *crow::connections::systemBus, serv, path,
1601 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001602 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001603 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001604 {
1605 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001606 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001607 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001608 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001609 return;
1610 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001611 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
George Liu9ae226f2023-06-21 17:56:46 +08001612 });
George Liue99073f2022-12-09 11:06:16 +08001613 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001614}
1615
1616/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301617 * @brief Sets boot properties into DBUS object(s).
1618 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001619 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001620 * @param[in] bootType The boot type to set.
1621 * @return Integer error code.
1622 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001623inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001624 const std::optional<std::string>& bootType)
1625{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001626 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001627
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001628 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001629 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001630 return;
1631 }
1632
1633 // Source target specified
1634 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1635 // Figure out which DBUS interface and property to use
1636 if (*bootType == "Legacy")
1637 {
1638 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1639 }
1640 else if (*bootType == "UEFI")
1641 {
1642 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1643 }
1644 else
1645 {
1646 BMCWEB_LOG_DEBUG << "Invalid property value for "
1647 "BootSourceOverrideMode: "
1648 << *bootType;
Ed Tanousac106bf2023-06-07 09:24:59 -07001649 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001650 "BootSourceOverrideMode");
1651 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001652 }
1653
1654 // Act on validated parameters
1655 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1656
George Liu9ae226f2023-06-21 17:56:46 +08001657 sdbusplus::asio::setProperty(
1658 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1659 "/xyz/openbmc_project/control/host0/boot",
1660 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001661 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001662 if (ec)
1663 {
1664 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1665 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001666 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001667 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001668 return;
1669 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001670 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001671 return;
1672 }
1673 BMCWEB_LOG_DEBUG << "Boot type update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001674 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001675}
1676
1677/**
1678 * @brief Sets boot properties into DBUS object(s).
1679 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001680 * @param[in] asyncResp Shared pointer for generating response
1681 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001682 * @param[in] bootType The boot type to set.
1683 * @return Integer error code.
1684 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001685inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001686 const std::optional<std::string>& bootEnable)
1687{
1688 if (!bootEnable)
1689 {
1690 return;
1691 }
1692 // Source target specified
1693 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1694
1695 bool bootOverrideEnable = false;
1696 bool bootOverridePersistent = false;
1697 // Figure out which DBUS interface and property to use
1698 if (*bootEnable == "Disabled")
1699 {
1700 bootOverrideEnable = false;
1701 }
1702 else if (*bootEnable == "Once")
1703 {
1704 bootOverrideEnable = true;
1705 bootOverridePersistent = false;
1706 }
1707 else if (*bootEnable == "Continuous")
1708 {
1709 bootOverrideEnable = true;
1710 bootOverridePersistent = true;
1711 }
1712 else
1713 {
George Liu0fda0f12021-11-16 10:06:17 +08001714 BMCWEB_LOG_DEBUG
1715 << "Invalid property value for BootSourceOverrideEnabled: "
1716 << *bootEnable;
Ed Tanousac106bf2023-06-07 09:24:59 -07001717 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001718 "BootSourceOverrideEnabled");
1719 return;
1720 }
1721
1722 // Act on validated parameters
1723 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1724
George Liu9ae226f2023-06-21 17:56:46 +08001725 sdbusplus::asio::setProperty(
1726 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1727 "/xyz/openbmc_project/control/host0/boot",
1728 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001729 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001730 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001731 {
Ed Tanous8a592812022-06-04 09:06:59 -07001732 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07001733 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001734 return;
1735 }
1736 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001737 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001738
1739 if (!bootOverrideEnable)
1740 {
1741 return;
1742 }
1743
1744 // In case boot override is enabled we need to set correct value for the
1745 // 'one_time' enable DBus interface
1746 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1747 << bootOverridePersistent;
1748
George Liu9ae226f2023-06-21 17:56:46 +08001749 sdbusplus::asio::setProperty(
1750 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1751 "/xyz/openbmc_project/control/host0/boot/one_time",
1752 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001753 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001754 if (ec)
1755 {
1756 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001757 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001758 return;
1759 }
1760 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001761 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001762}
1763
1764/**
1765 * @brief Sets boot properties into DBUS object(s).
1766 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001767 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301768 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301769 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001770 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301771 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001772inline void
1773 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1774 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301775{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001776 std::string bootSourceStr;
1777 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001778
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001779 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301780 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001781 return;
1782 }
1783
1784 // Source target specified
1785 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1786 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001787 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1788 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001789 {
1790 BMCWEB_LOG_DEBUG
1791 << "Invalid property value for BootSourceOverrideTarget: "
1792 << *bootSource;
Ed Tanousac106bf2023-06-07 09:24:59 -07001793 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001794 "BootSourceTargetOverride");
1795 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001796 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301797
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001798 // Act on validated parameters
1799 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1800 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001801
George Liu9ae226f2023-06-21 17:56:46 +08001802 sdbusplus::asio::setProperty(
1803 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1804 "/xyz/openbmc_project/control/host0/boot",
1805 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001806 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001807 if (ec)
1808 {
1809 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001810 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001811 return;
1812 }
1813 BMCWEB_LOG_DEBUG << "Boot source update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001814 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001815
George Liu9ae226f2023-06-21 17:56:46 +08001816 sdbusplus::asio::setProperty(
1817 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1818 "/xyz/openbmc_project/control/host0/boot",
1819 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001820 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001821 if (ec)
1822 {
1823 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001824 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001825 return;
1826 }
1827 BMCWEB_LOG_DEBUG << "Boot mode update done.";
George Liu9ae226f2023-06-21 17:56:46 +08001828 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001829}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001830
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001831/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001832 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301833 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001834 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301835 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001836 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301837 * @param[in] bootEnable The boot override enable from incoming RF request.
1838 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001839 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301840 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001841
Ed Tanousac106bf2023-06-07 09:24:59 -07001842inline void
1843 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1844 const std::optional<std::string>& bootSource,
1845 const std::optional<std::string>& bootType,
1846 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301847{
1848 BMCWEB_LOG_DEBUG << "Set boot information.";
1849
Ed Tanousac106bf2023-06-07 09:24:59 -07001850 setBootModeOrSource(asyncResp, bootSource);
1851 setBootType(asyncResp, bootType);
1852 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301853}
1854
George Liuc6a620f2020-04-10 17:18:11 +08001855/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001856 * @brief Sets AssetTag
1857 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001858 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001859 * @param[in] assetTag "AssetTag" from request.
1860 *
1861 * @return None.
1862 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001863inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001864 const std::string& assetTag)
1865{
George Liue99073f2022-12-09 11:06:16 +08001866 constexpr std::array<std::string_view, 1> interfaces = {
1867 "xyz.openbmc_project.Inventory.Item.System"};
1868 dbus::utility::getSubTree(
1869 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001870 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001871 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001872 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001873 if (ec)
1874 {
1875 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07001876 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001877 return;
1878 }
1879 if (subtree.empty())
1880 {
1881 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001882 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001883 return;
1884 }
1885 // Assume only 1 system D-Bus object
1886 // Throw an error if there is more than 1
1887 if (subtree.size() > 1)
1888 {
1889 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001890 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001891 return;
1892 }
1893 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1894 {
1895 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001896 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001897 return;
1898 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001899
Ed Tanous002d39b2022-05-31 08:59:27 -07001900 const std::string& path = subtree[0].first;
1901 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001902
Ed Tanous002d39b2022-05-31 08:59:27 -07001903 if (service.empty())
1904 {
1905 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07001906 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001907 return;
1908 }
1909
George Liu9ae226f2023-06-21 17:56:46 +08001910 sdbusplus::asio::setProperty(
1911 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001912 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001913 assetTag, [asyncResp](const boost::system::error_code& ec2) {
1914 if (ec2)
1915 {
1916 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1917 << ec2;
1918 messages::internalError(asyncResp->res);
1919 return;
1920 }
1921 });
George Liue99073f2022-12-09 11:06:16 +08001922 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001923}
1924
1925/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001926 * @brief Validate the specified stopBootOnFault is valid and return the
1927 * stopBootOnFault name associated with that string
1928 *
1929 * @param[in] stopBootOnFaultString String representing the desired
1930 * stopBootOnFault
1931 *
1932 * @return stopBootOnFault value or empty if incoming value is not valid
1933 */
1934inline std::optional<bool>
1935 validstopBootOnFault(const std::string& stopBootOnFaultString)
1936{
1937 if (stopBootOnFaultString == "AnyFault")
1938 {
1939 return true;
1940 }
1941
1942 if (stopBootOnFaultString == "Never")
1943 {
1944 return false;
1945 }
1946
1947 return std::nullopt;
1948}
1949
1950/**
1951 * @brief Sets stopBootOnFault
1952 *
1953 * @param[in] aResp Shared pointer for generating response message.
1954 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1955 *
1956 * @return None.
1957 */
1958inline void setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1959 const std::string& stopBootOnFault)
1960{
1961 BMCWEB_LOG_DEBUG << "Set Stop Boot On Fault.";
1962
1963 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1964 if (!stopBootEnabled)
1965 {
1966 BMCWEB_LOG_DEBUG << "Invalid property value for StopBootOnFault: "
1967 << stopBootOnFault;
1968 messages::propertyValueNotInList(aResp->res, stopBootOnFault,
1969 "StopBootOnFault");
1970 return;
1971 }
1972
1973 sdbusplus::asio::setProperty(*crow::connections::systemBus,
1974 "xyz.openbmc_project.Settings",
1975 "/xyz/openbmc_project/logging/settings",
1976 "xyz.openbmc_project.Logging.Settings",
1977 "QuiesceOnHwError", *stopBootEnabled,
1978 [aResp](const boost::system::error_code& ec) {
1979 if (ec)
1980 {
1981 if (ec.value() != EBADR)
1982 {
1983 messages::internalError(aResp->res);
1984 }
1985 return;
1986 }
1987 });
1988}
1989
1990/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001991 * @brief Sets automaticRetry (Auto Reboot)
1992 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001993 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001994 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1995 *
1996 * @return None.
1997 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001998inline void
1999 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2000 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05002001{
2002 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
2003
2004 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08002005 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05002006
2007 if (automaticRetryConfig == "Disabled")
2008 {
2009 autoRebootEnabled = false;
2010 }
2011 else if (automaticRetryConfig == "RetryAttempts")
2012 {
2013 autoRebootEnabled = true;
2014 }
2015 else
2016 {
George Liu0fda0f12021-11-16 10:06:17 +08002017 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05002018 << automaticRetryConfig;
Ed Tanousac106bf2023-06-07 09:24:59 -07002019 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05002020 "AutomaticRetryConfig");
2021 return;
2022 }
2023
George Liu9ae226f2023-06-21 17:56:46 +08002024 sdbusplus::asio::setProperty(
2025 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05002026 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05002027 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08002028 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
2029 if (ec)
2030 {
2031 messages::internalError(asyncResp->res);
2032 return;
2033 }
2034 });
Gunnar Mills69f35302020-05-17 16:06:31 -05002035}
2036
Ed Tanous8d69c662023-06-21 10:29:06 -07002037inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
2038{
2039 if (policy == "AlwaysOn")
2040 {
2041 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
2042 }
2043 if (policy == "AlwaysOff")
2044 {
2045 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
2046 }
2047 if (policy == "LastState")
2048 {
2049 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
2050 }
2051 return "";
2052}
2053
Gunnar Mills69f35302020-05-17 16:06:31 -05002054/**
George Liuc6a620f2020-04-10 17:18:11 +08002055 * @brief Sets power restore policy properties.
2056 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002057 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08002058 * @param[in] policy power restore policy properties from request.
2059 *
2060 * @return None.
2061 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002062inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002063 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07002064 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002065{
2066 BMCWEB_LOG_DEBUG << "Set power restore policy.";
2067
Ed Tanous8d69c662023-06-21 10:29:06 -07002068 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002069
Ed Tanous8d69c662023-06-21 10:29:06 -07002070 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002071 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002072 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002073 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002074 return;
2075 }
2076
George Liu9ae226f2023-06-21 17:56:46 +08002077 sdbusplus::asio::setProperty(
2078 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002079 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002080 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002081 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
2082 if (ec)
2083 {
2084 messages::internalError(asyncResp->res);
2085 return;
2086 }
2087 });
George Liuc6a620f2020-04-10 17:18:11 +08002088}
2089
AppaRao Pulia6349912019-10-18 17:16:08 +05302090#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2091/**
2092 * @brief Retrieves provisioning status
2093 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002094 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302095 *
2096 * @return None.
2097 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002098inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302099{
2100 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002101 sdbusplus::asio::getAllProperties(
2102 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2103 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002104 [asyncResp](const boost::system::error_code& ec,
2105 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002106 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002107 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2108 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002109 "#OemComputerSystem.OpenBmc";
2110 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002111
Ed Tanous002d39b2022-05-31 08:59:27 -07002112 if (ec)
2113 {
2114 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2115 // not an error, don't have to have the interface
2116 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2117 return;
2118 }
2119
2120 const bool* provState = nullptr;
2121 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002122
2123 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002124 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2125 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002126
2127 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002128 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002129 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002130 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002131 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302132
Ed Tanous002d39b2022-05-31 08:59:27 -07002133 if ((provState == nullptr) || (lockState == nullptr))
2134 {
2135 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
Ed Tanousac106bf2023-06-07 09:24:59 -07002136 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002137 return;
2138 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302139
Ed Tanous002d39b2022-05-31 08:59:27 -07002140 if (*provState == true)
2141 {
2142 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302143 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002144 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302145 }
2146 else
2147 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002148 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302149 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002150 }
2151 else
2152 {
2153 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2154 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002155 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302156}
2157#endif
2158
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302159/**
Chris Cain3a2d04242021-05-28 16:57:10 -05002160 * @brief Translate the PowerMode to a response message.
2161 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002162 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002163 * @param[in] modeValue PowerMode value to be translated
2164 *
2165 * @return None.
2166 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002167inline void
2168 translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2169 const std::string& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002170{
George Liu0fda0f12021-11-16 10:06:17 +08002171 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002172 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002173 asyncResp->res.jsonValue["PowerMode"] = "Static";
Chris Cain3a2d04242021-05-28 16:57:10 -05002174 }
George Liu0fda0f12021-11-16 10:06:17 +08002175 else if (
2176 modeValue ==
2177 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002178 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002179 asyncResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002180 }
George Liu0fda0f12021-11-16 10:06:17 +08002181 else if (modeValue ==
2182 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002183 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002184 asyncResp->res.jsonValue["PowerMode"] = "PowerSaving";
Chris Cain3a2d04242021-05-28 16:57:10 -05002185 }
George Liu0fda0f12021-11-16 10:06:17 +08002186 else if (modeValue ==
2187 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002188 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002189 asyncResp->res.jsonValue["PowerMode"] = "OEM";
Chris Cain3a2d04242021-05-28 16:57:10 -05002190 }
2191 else
2192 {
2193 // Any other values would be invalid
2194 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
Ed Tanousac106bf2023-06-07 09:24:59 -07002195 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002196 }
2197}
2198
2199/**
2200 * @brief Retrieves system power mode
2201 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002202 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002203 *
2204 * @return None.
2205 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002206inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002207{
2208 BMCWEB_LOG_DEBUG << "Get power mode.";
2209
2210 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002211 constexpr std::array<std::string_view, 1> interfaces = {
2212 "xyz.openbmc_project.Control.Power.Mode"};
2213 dbus::utility::getSubTree(
2214 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002215 [asyncResp](const boost::system::error_code& ec,
2216 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002217 if (ec)
2218 {
2219 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2220 << ec;
2221 // This is an optional D-Bus object so just return if
2222 // error occurs
2223 return;
2224 }
2225 if (subtree.empty())
2226 {
2227 // As noted above, this is an optional interface so just return
2228 // if there is no instance found
2229 return;
2230 }
2231 if (subtree.size() > 1)
2232 {
2233 // More then one PowerMode object is not supported and is an
2234 // error
2235 BMCWEB_LOG_DEBUG
2236 << "Found more than 1 system D-Bus Power.Mode objects: "
2237 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002238 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002239 return;
2240 }
2241 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2242 {
2243 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002244 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002245 return;
2246 }
2247 const std::string& path = subtree[0].first;
2248 const std::string& service = subtree[0].second.begin()->first;
2249 if (service.empty())
2250 {
2251 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002252 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002253 return;
2254 }
2255 // Valid Power Mode object found, now read the current value
2256 sdbusplus::asio::getProperty<std::string>(
2257 *crow::connections::systemBus, service, path,
2258 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002259 [asyncResp](const boost::system::error_code& ec2,
2260 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002261 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002262 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002263 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002264 << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002265 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002266 return;
2267 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002268
Ed Tanousac106bf2023-06-07 09:24:59 -07002269 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
Ed Tanous002d39b2022-05-31 08:59:27 -07002270 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002271
Ed Tanous002d39b2022-05-31 08:59:27 -07002272 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
Ed Tanousac106bf2023-06-07 09:24:59 -07002273 translatePowerMode(asyncResp, pmode);
Ed Tanous002d39b2022-05-31 08:59:27 -07002274 });
George Liue99073f2022-12-09 11:06:16 +08002275 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002276}
2277
2278/**
2279 * @brief Validate the specified mode is valid and return the PowerMode
2280 * name associated with that string
2281 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002283 * @param[in] modeString String representing the desired PowerMode
2284 *
2285 * @return PowerMode value or empty string if mode is not valid
2286 */
2287inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002288 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002289 const std::string& modeString)
2290{
2291 std::string mode;
2292
2293 if (modeString == "Static")
2294 {
2295 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2296 }
2297 else if (modeString == "MaximumPerformance")
2298 {
George Liu0fda0f12021-11-16 10:06:17 +08002299 mode =
2300 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002301 }
2302 else if (modeString == "PowerSaving")
2303 {
2304 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2305 }
2306 else
2307 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002308 messages::propertyValueNotInList(asyncResp->res, modeString,
2309 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002310 }
2311 return mode;
2312}
2313
2314/**
2315 * @brief Sets system power mode.
2316 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002317 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002318 * @param[in] pmode System power mode from request.
2319 *
2320 * @return None.
2321 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002322inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002323 const std::string& pmode)
2324{
2325 BMCWEB_LOG_DEBUG << "Set power mode.";
2326
Ed Tanousac106bf2023-06-07 09:24:59 -07002327 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002328 if (powerMode.empty())
2329 {
2330 return;
2331 }
2332
2333 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002334 constexpr std::array<std::string_view, 1> interfaces = {
2335 "xyz.openbmc_project.Control.Power.Mode"};
2336 dbus::utility::getSubTree(
2337 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002338 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002339 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002340 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002341 if (ec)
2342 {
2343 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2344 << ec;
2345 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002346 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002347 return;
2348 }
2349 if (subtree.empty())
2350 {
2351 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002352 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002353 "PowerMode");
2354 return;
2355 }
2356 if (subtree.size() > 1)
2357 {
2358 // More then one PowerMode object is not supported and is an
2359 // error
2360 BMCWEB_LOG_DEBUG
2361 << "Found more than 1 system D-Bus Power.Mode objects: "
2362 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002363 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002364 return;
2365 }
2366 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2367 {
2368 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002369 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002370 return;
2371 }
2372 const std::string& path = subtree[0].first;
2373 const std::string& service = subtree[0].second.begin()->first;
2374 if (service.empty())
2375 {
2376 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002377 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002378 return;
2379 }
2380
2381 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2382 << path;
2383
2384 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002385 sdbusplus::asio::setProperty(
2386 *crow::connections::systemBus, service, path,
2387 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002388 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002389 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002390 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002391 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002392 return;
2393 }
George Liu9ae226f2023-06-21 17:56:46 +08002394 });
George Liue99073f2022-12-09 11:06:16 +08002395 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002396}
2397
2398/**
Yong Li51709ff2019-09-30 14:13:04 +08002399 * @brief Translates watchdog timeout action DBUS property value to redfish.
2400 *
2401 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2402 *
2403 * @return Returns as a string, the timeout action in Redfish terms. If
2404 * translation cannot be done, returns an empty string.
2405 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002406inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002407{
2408 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2409 {
2410 return "None";
2411 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002412 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002413 {
2414 return "ResetSystem";
2415 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002416 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002417 {
2418 return "PowerDown";
2419 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002420 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002421 {
2422 return "PowerCycle";
2423 }
2424
2425 return "";
2426}
2427
2428/**
Yong Lic45f0082019-10-10 14:19:01 +08002429 *@brief Translates timeout action from Redfish to DBUS property value.
2430 *
2431 *@param[in] rfAction The timeout action in Redfish.
2432 *
2433 *@return Returns as a string, the time_out action as expected by DBUS.
2434 *If translation cannot be done, returns an empty string.
2435 */
2436
Ed Tanous23a21a12020-07-25 04:45:05 +00002437inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002438{
2439 if (rfAction == "None")
2440 {
2441 return "xyz.openbmc_project.State.Watchdog.Action.None";
2442 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002443 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002444 {
2445 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2446 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002447 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002448 {
2449 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2450 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002451 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002452 {
2453 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2454 }
2455
2456 return "";
2457}
2458
2459/**
Yong Li51709ff2019-09-30 14:13:04 +08002460 * @brief Retrieves host watchdog timer properties over DBUS
2461 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002462 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002463 *
2464 * @return None.
2465 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002466inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002467 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002468{
2469 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002470 sdbusplus::asio::getAllProperties(
2471 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2472 "/xyz/openbmc_project/watchdog/host0",
2473 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002474 [asyncResp](const boost::system::error_code& ec,
2475 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002476 if (ec)
2477 {
2478 // watchdog service is stopped
2479 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2480 return;
2481 }
2482
2483 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2484
2485 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002486 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002487
2488 // watchdog service is running/enabled
2489 hostWatchdogTimer["Status"]["State"] = "Enabled";
2490
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002491 const bool* enabled = nullptr;
2492 const std::string* expireAction = nullptr;
2493
2494 const bool success = sdbusplus::unpackPropertiesNoThrow(
2495 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2496 "ExpireAction", expireAction);
2497
2498 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002499 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002500 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002501 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002502 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002503
2504 if (enabled != nullptr)
2505 {
2506 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2507 }
2508
2509 if (expireAction != nullptr)
2510 {
2511 std::string action = dbusToRfWatchdogAction(*expireAction);
2512 if (action.empty())
2513 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002514 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002515 return;
2516 }
2517 hostWatchdogTimer["TimeoutAction"] = action;
2518 }
2519 });
Yong Li51709ff2019-09-30 14:13:04 +08002520}
2521
2522/**
Yong Lic45f0082019-10-10 14:19:01 +08002523 * @brief Sets Host WatchDog Timer properties.
2524 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002525 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002526 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2527 * RF request.
2528 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2529 *
2530 * @return None.
2531 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002532inline void
2533 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2534 const std::optional<bool> wdtEnable,
2535 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002536{
2537 BMCWEB_LOG_DEBUG << "Set host watchdog";
2538
2539 if (wdtTimeOutAction)
2540 {
2541 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2542 // check if TimeOut Action is Valid
2543 if (wdtTimeOutActStr.empty())
2544 {
2545 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2546 << *wdtTimeOutAction;
Ed Tanousac106bf2023-06-07 09:24:59 -07002547 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002548 "TimeoutAction");
2549 return;
2550 }
2551
George Liu9ae226f2023-06-21 17:56:46 +08002552 sdbusplus::asio::setProperty(
2553 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002554 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002555 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002556 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
2557 if (ec)
2558 {
2559 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2560 messages::internalError(asyncResp->res);
2561 return;
2562 }
2563 });
Yong Lic45f0082019-10-10 14:19:01 +08002564 }
2565
2566 if (wdtEnable)
2567 {
George Liu9ae226f2023-06-21 17:56:46 +08002568 sdbusplus::asio::setProperty(
2569 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2570 "/xyz/openbmc_project/watchdog/host0",
2571 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002572 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002573 if (ec)
2574 {
2575 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002576 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002577 return;
2578 }
George Liu9ae226f2023-06-21 17:56:46 +08002579 });
Yong Lic45f0082019-10-10 14:19:01 +08002580 }
2581}
2582
Chris Cain37bbf982021-09-20 10:53:09 -05002583/**
2584 * @brief Parse the Idle Power Saver properties into json
2585 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002586 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002587 * @param[in] properties IPS property data from DBus.
2588 *
2589 * @return true if successful
2590 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002591inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002592 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002593 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002594{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002595 const bool* enabled = nullptr;
2596 const uint8_t* enterUtilizationPercent = nullptr;
2597 const uint64_t* enterDwellTime = nullptr;
2598 const uint8_t* exitUtilizationPercent = nullptr;
2599 const uint64_t* exitDwellTime = nullptr;
2600
2601 const bool success = sdbusplus::unpackPropertiesNoThrow(
2602 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002603 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2604 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2605 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002606
2607 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002608 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002609 return false;
2610 }
2611
2612 if (enabled != nullptr)
2613 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002614 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002615 }
2616
2617 if (enterUtilizationPercent != nullptr)
2618 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002619 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002620 *enterUtilizationPercent;
2621 }
2622
2623 if (enterDwellTime != nullptr)
2624 {
2625 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002626 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002627 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2628 .count();
2629 }
2630
2631 if (exitUtilizationPercent != nullptr)
2632 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002633 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002634 *exitUtilizationPercent;
2635 }
2636
2637 if (exitDwellTime != nullptr)
2638 {
2639 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002640 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002641 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2642 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002643 }
2644
2645 return true;
2646}
2647
2648/**
2649 * @brief Retrieves host watchdog timer properties over DBUS
2650 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002651 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002652 *
2653 * @return None.
2654 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002655inline void
2656 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002657{
2658 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2659
2660 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002661 constexpr std::array<std::string_view, 1> interfaces = {
2662 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2663 dbus::utility::getSubTree(
2664 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002665 [asyncResp](const boost::system::error_code& ec,
2666 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002667 if (ec)
2668 {
2669 BMCWEB_LOG_DEBUG
2670 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2671 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002672 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002673 return;
2674 }
2675 if (subtree.empty())
2676 {
2677 // This is an optional interface so just return
2678 // if there is no instance found
2679 BMCWEB_LOG_DEBUG << "No instances found";
2680 return;
2681 }
2682 if (subtree.size() > 1)
2683 {
2684 // More then one PowerIdlePowerSaver object is not supported and
2685 // is an error
2686 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2687 "Power.IdlePowerSaver objects: "
2688 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002689 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002690 return;
2691 }
2692 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2693 {
2694 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002695 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002696 return;
2697 }
2698 const std::string& path = subtree[0].first;
2699 const std::string& service = subtree[0].second.begin()->first;
2700 if (service.empty())
2701 {
2702 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002703 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002704 return;
2705 }
2706
2707 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002708 sdbusplus::asio::getAllProperties(
2709 *crow::connections::systemBus, service, path,
2710 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002711 [asyncResp](const boost::system::error_code& ec2,
2712 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002713 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002714 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002715 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002716 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002717 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002718 return;
2719 }
2720
Ed Tanousac106bf2023-06-07 09:24:59 -07002721 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002722 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002723 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002724 return;
2725 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002726 });
George Liue99073f2022-12-09 11:06:16 +08002727 });
Chris Cain37bbf982021-09-20 10:53:09 -05002728
2729 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2730}
2731
2732/**
2733 * @brief Sets Idle Power Saver properties.
2734 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002735 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002736 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2737 * RF request.
2738 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2739 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2740 * before entering idle state.
2741 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2742 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2743 * before exiting idle state
2744 *
2745 * @return None.
2746 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002747inline void
2748 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2749 const std::optional<bool> ipsEnable,
2750 const std::optional<uint8_t> ipsEnterUtil,
2751 const std::optional<uint64_t> ipsEnterTime,
2752 const std::optional<uint8_t> ipsExitUtil,
2753 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002754{
2755 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2756
2757 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002758 constexpr std::array<std::string_view, 1> interfaces = {
2759 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2760 dbus::utility::getSubTree(
2761 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002762 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002763 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002764 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002765 if (ec)
2766 {
2767 BMCWEB_LOG_DEBUG
2768 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2769 << ec;
Ed Tanousac106bf2023-06-07 09:24:59 -07002770 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002771 return;
2772 }
2773 if (subtree.empty())
2774 {
2775 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002776 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002777 "IdlePowerSaver");
2778 return;
2779 }
2780 if (subtree.size() > 1)
2781 {
2782 // More then one PowerIdlePowerSaver object is not supported and
2783 // is an error
2784 BMCWEB_LOG_DEBUG
2785 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2786 << subtree.size();
Ed Tanousac106bf2023-06-07 09:24:59 -07002787 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002788 return;
2789 }
2790 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2791 {
2792 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002793 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002794 return;
2795 }
2796 const std::string& path = subtree[0].first;
2797 const std::string& service = subtree[0].second.begin()->first;
2798 if (service.empty())
2799 {
2800 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
Ed Tanousac106bf2023-06-07 09:24:59 -07002801 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002802 return;
2803 }
Chris Cain37bbf982021-09-20 10:53:09 -05002804
Ed Tanous002d39b2022-05-31 08:59:27 -07002805 // Valid Power IdlePowerSaver object found, now set any values that
2806 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002807
Ed Tanous002d39b2022-05-31 08:59:27 -07002808 if (ipsEnable)
2809 {
George Liu9ae226f2023-06-21 17:56:46 +08002810 sdbusplus::asio::setProperty(
2811 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002812 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002813 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
2814 if (ec2)
2815 {
2816 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
2817 messages::internalError(asyncResp->res);
2818 return;
2819 }
2820 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002821 }
2822 if (ipsEnterUtil)
2823 {
George Liu9ae226f2023-06-21 17:56:46 +08002824 sdbusplus::asio::setProperty(
2825 *crow::connections::systemBus, service, path,
2826 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2827 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002828 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002829 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002830 {
Ed Tanous8a592812022-06-04 09:06:59 -07002831 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002832 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002833 return;
2834 }
George Liu9ae226f2023-06-21 17:56:46 +08002835 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002836 }
2837 if (ipsEnterTime)
2838 {
2839 // Convert from seconds into milliseconds for DBus
2840 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002841 sdbusplus::asio::setProperty(
2842 *crow::connections::systemBus, service, path,
2843 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2844 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002845 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002846 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002847 {
Ed Tanous8a592812022-06-04 09:06:59 -07002848 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002849 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002850 return;
2851 }
George Liu9ae226f2023-06-21 17:56:46 +08002852 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002853 }
2854 if (ipsExitUtil)
2855 {
George Liu9ae226f2023-06-21 17:56:46 +08002856 sdbusplus::asio::setProperty(
2857 *crow::connections::systemBus, service, path,
2858 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2859 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002860 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002861 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002862 {
Ed Tanous8a592812022-06-04 09:06:59 -07002863 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002864 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002865 return;
2866 }
George Liu9ae226f2023-06-21 17:56:46 +08002867 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002868 }
2869 if (ipsExitTime)
2870 {
2871 // Convert from seconds into milliseconds for DBus
2872 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002873 sdbusplus::asio::setProperty(
2874 *crow::connections::systemBus, service, path,
2875 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2876 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002877 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002878 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002879 {
Ed Tanous8a592812022-06-04 09:06:59 -07002880 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanousac106bf2023-06-07 09:24:59 -07002881 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002882 return;
2883 }
George Liu9ae226f2023-06-21 17:56:46 +08002884 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002885 }
George Liue99073f2022-12-09 11:06:16 +08002886 });
Chris Cain37bbf982021-09-20 10:53:09 -05002887
2888 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2889}
2890
Ed Tanousc1e219d2023-06-07 10:34:33 -07002891inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002892 crow::App& app, const crow::Request& req,
2893 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2894{
2895 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2896 {
2897 return;
2898 }
2899 asyncResp->res.addHeader(
2900 boost::beast::http::field::link,
2901 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2902}
2903
Ed Tanousc1e219d2023-06-07 10:34:33 -07002904inline void handleComputerSystemCollectionGet(
2905 crow::App& app, const crow::Request& req,
2906 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2907{
2908 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2909 {
2910 return;
2911 }
2912
2913 asyncResp->res.addHeader(
2914 boost::beast::http::field::link,
2915 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2916 asyncResp->res.jsonValue["@odata.type"] =
2917 "#ComputerSystemCollection.ComputerSystemCollection";
2918 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2919 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2920
2921 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2922 ifaceArray = nlohmann::json::array();
2923 if constexpr (bmcwebEnableMultiHost)
2924 {
2925 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2926 // Option currently returns no systems. TBD
2927 return;
2928 }
2929 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2930 nlohmann::json::object_t system;
2931 system["@odata.id"] = "/redfish/v1/Systems/system";
2932 ifaceArray.emplace_back(std::move(system));
2933 sdbusplus::asio::getProperty<std::string>(
2934 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2935 "/xyz/openbmc_project/network/hypervisor",
2936 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2937 [asyncResp](const boost::system::error_code& ec2,
2938 const std::string& /*hostName*/) {
2939 if (ec2)
2940 {
2941 return;
2942 }
2943 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2944 if (val == asyncResp->res.jsonValue.end())
2945 {
2946 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2947 return;
2948 }
2949 uint64_t* count = val->get_ptr<uint64_t*>();
2950 if (count == nullptr)
2951 {
2952 BMCWEB_LOG_CRITICAL << "Count wasn't found??";
2953 return;
2954 }
2955 *count = *count + 1;
2956 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2957 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2958 nlohmann::json::object_t hypervisor;
2959 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2960 ifaceArray2.emplace_back(std::move(hypervisor));
2961 });
2962}
2963
Yong Lic45f0082019-10-10 14:19:01 +08002964/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002965 * Function transceives data with dbus directly.
2966 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002967inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002968{
Patrick Williams89492a12023-05-10 07:51:34 -05002969 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2970 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2971 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002972 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002973 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002974
2975 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002976 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002977 if (ec)
2978 {
2979 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2980 messages::internalError(asyncResp->res);
2981 return;
2982 }
2983 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002984 },
2985 serviceName, objectPath, interfaceName, method);
2986}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002987
2988/**
Andrew Geisslerfc903b32023-05-31 14:15:42 -04002989 * Handle error responses from d-bus for system power requests
2990 */
2991inline void handleSystemActionResetError(const boost::system::error_code& ec,
2992 const sdbusplus::message_t& eMsg,
2993 std::string_view resetType,
2994 crow::Response& res)
2995{
2996 if (ec.value() == boost::asio::error::invalid_argument)
2997 {
2998 messages::actionParameterNotSupported(res, resetType, "Reset");
2999 return;
3000 }
3001
3002 if (eMsg.get_error() == nullptr)
3003 {
3004 BMCWEB_LOG_ERROR << "D-Bus response error: " << ec;
3005 messages::internalError(res);
3006 return;
3007 }
3008 std::string_view errorMessage = eMsg.get_error()->name;
3009
3010 // If operation failed due to BMC not being in Ready state, tell
3011 // user to retry in a bit
3012 if ((errorMessage ==
3013 std::string_view(
3014 "xyz.openbmc_project.State.Chassis.Error.BMCNotReady")) ||
3015 (errorMessage ==
3016 std::string_view("xyz.openbmc_project.State.Host.Error.BMCNotReady")))
3017 {
3018 BMCWEB_LOG_DEBUG << "BMC not ready, operation not allowed right now";
3019 messages::serviceTemporarilyUnavailable(res, "10");
3020 return;
3021 }
3022
3023 BMCWEB_LOG_ERROR << "System Action Reset transition fail " << ec
3024 << " sdbusplus:" << errorMessage;
3025 messages::internalError(res);
3026}
3027
Ed Tanousc1e219d2023-06-07 10:34:33 -07003028inline void handleComputerSystemResetActionPost(
3029 crow::App& app, const crow::Request& req,
3030 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3031 const std::string& systemName)
3032{
3033 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3034 {
3035 return;
3036 }
3037 if (systemName != "system")
3038 {
3039 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3040 systemName);
3041 return;
3042 }
3043 if constexpr (bmcwebEnableMultiHost)
3044 {
3045 // Option currently returns no systems. TBD
3046 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3047 systemName);
3048 return;
3049 }
3050 std::string resetType;
3051 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3052 {
3053 return;
3054 }
3055
3056 // Get the command and host vs. chassis
3057 std::string command;
3058 bool hostCommand = true;
3059 if ((resetType == "On") || (resetType == "ForceOn"))
3060 {
3061 command = "xyz.openbmc_project.State.Host.Transition.On";
3062 hostCommand = true;
3063 }
3064 else if (resetType == "ForceOff")
3065 {
3066 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3067 hostCommand = false;
3068 }
3069 else if (resetType == "ForceRestart")
3070 {
3071 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3072 hostCommand = true;
3073 }
3074 else if (resetType == "GracefulShutdown")
3075 {
3076 command = "xyz.openbmc_project.State.Host.Transition.Off";
3077 hostCommand = true;
3078 }
3079 else if (resetType == "GracefulRestart")
3080 {
3081 command =
3082 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3083 hostCommand = true;
3084 }
3085 else if (resetType == "PowerCycle")
3086 {
3087 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3088 hostCommand = true;
3089 }
3090 else if (resetType == "Nmi")
3091 {
3092 doNMI(asyncResp);
3093 return;
3094 }
3095 else
3096 {
3097 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3098 return;
3099 }
3100
3101 if (hostCommand)
3102 {
George Liu9ae226f2023-06-21 17:56:46 +08003103 sdbusplus::asio::setProperty(
3104 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3105 "/xyz/openbmc_project/state/host0",
3106 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
3107 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003108 [asyncResp, resetType](const boost::system::error_code& ec,
3109 sdbusplus::message_t& sdbusErrMsg) {
3110 if (ec)
3111 {
3112 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3113 asyncResp->res);
3114
3115 return;
3116 }
3117 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003118 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003119 }
3120 else
3121 {
George Liu9ae226f2023-06-21 17:56:46 +08003122 sdbusplus::asio::setProperty(
3123 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
3124 "/xyz/openbmc_project/state/chassis0",
3125 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
3126 command,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003127 [asyncResp, resetType](const boost::system::error_code& ec,
3128 sdbusplus::message_t& sdbusErrMsg) {
3129 if (ec)
3130 {
3131 handleSystemActionResetError(ec, sdbusErrMsg, resetType,
3132 asyncResp->res);
3133 return;
3134 }
3135 messages::success(asyncResp->res);
George Liu9ae226f2023-06-21 17:56:46 +08003136 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003137 }
3138}
3139
Ed Tanousc1e219d2023-06-07 10:34:33 -07003140inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003141 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003142 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3143 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003144{
3145 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3146 {
3147 return;
3148 }
3149
3150 asyncResp->res.addHeader(
3151 boost::beast::http::field::link,
3152 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3153}
3154
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003155inline void afterPortRequest(
3156 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3157 const boost::system::error_code& ec,
3158 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3159{
3160 if (ec)
3161 {
3162 messages::internalError(asyncResp->res);
3163 return;
3164 }
3165 for (const auto& data : socketData)
3166 {
3167 const std::string& socketPath = get<0>(data);
3168 const std::string& protocolName = get<1>(data);
3169 bool isProtocolEnabled = get<2>(data);
3170 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3171 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3172 // need to retrieve port number for
3173 // obmc-console-ssh service
3174 if (protocolName == "SSH")
3175 {
3176 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003177 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003178 int portNumber) {
3179 if (ec1)
3180 {
3181 messages::internalError(asyncResp->res);
3182 return;
3183 }
3184 nlohmann::json& dataJson1 =
3185 asyncResp->res.jsonValue["SerialConsole"];
3186 dataJson1[protocolName]["Port"] = portNumber;
3187 });
3188 }
3189 }
3190}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003191
3192inline void
3193 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3194 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3195 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003196{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003197 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3198 {
3199 return;
3200 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003201
Ed Tanousc1e219d2023-06-07 10:34:33 -07003202 if constexpr (bmcwebEnableMultiHost)
3203 {
3204 // Option currently returns no systems. TBD
3205 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3206 systemName);
3207 return;
3208 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003209
Ed Tanousc1e219d2023-06-07 10:34:33 -07003210 if (systemName == "hypervisor")
3211 {
3212 handleHypervisorSystemGet(asyncResp);
3213 return;
3214 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003215
Ed Tanousc1e219d2023-06-07 10:34:33 -07003216 if (systemName != "system")
3217 {
3218 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3219 systemName);
3220 return;
3221 }
3222 asyncResp->res.addHeader(
3223 boost::beast::http::field::link,
3224 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3225 asyncResp->res.jsonValue["@odata.type"] =
3226 "#ComputerSystem.v1_16_0.ComputerSystem";
3227 asyncResp->res.jsonValue["Name"] = "system";
3228 asyncResp->res.jsonValue["Id"] = "system";
3229 asyncResp->res.jsonValue["SystemType"] = "Physical";
3230 asyncResp->res.jsonValue["Description"] = "Computer System";
3231 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
3232 if constexpr (bmcwebEnableProcMemStatus)
3233 {
3234 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
3235 "Disabled";
3236 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
3237 "Disabled";
3238 }
3239 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003240 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003241 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003242
Ed Tanousc1e219d2023-06-07 10:34:33 -07003243 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3244 "/redfish/v1/Systems/system/Processors";
3245 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3246 "/redfish/v1/Systems/system/Memory";
3247 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3248 "/redfish/v1/Systems/system/Storage";
3249 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3250 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003251
Ed Tanousc1e219d2023-06-07 10:34:33 -07003252 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3253 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3254 asyncResp->res
3255 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3256 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003257
Ed Tanousc1e219d2023-06-07 10:34:33 -07003258 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3259 "/redfish/v1/Systems/system/LogServices";
3260 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3261 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003262
Ed Tanousc1e219d2023-06-07 10:34:33 -07003263 nlohmann::json::array_t managedBy;
3264 nlohmann::json& manager = managedBy.emplace_back();
3265 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3266 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3267 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3268 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003269
Ed Tanousc1e219d2023-06-07 10:34:33 -07003270 // Fill in SerialConsole info
3271 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3272 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003273
Ed Tanousc1e219d2023-06-07 10:34:33 -07003274 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3275 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3276 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3277 "Press ~. to exit console";
3278 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3279 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003280
3281#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003282 // Fill in GraphicalConsole info
3283 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3284 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3285 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3286 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003287
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003288#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003289
Ed Tanousc1e219d2023-06-07 10:34:33 -07003290 auto health = std::make_shared<HealthPopulate>(asyncResp);
3291 if constexpr (bmcwebEnableHealthPopulate)
3292 {
3293 constexpr std::array<std::string_view, 4> inventoryForSystems{
3294 "xyz.openbmc_project.Inventory.Item.Dimm",
3295 "xyz.openbmc_project.Inventory.Item.Cpu",
3296 "xyz.openbmc_project.Inventory.Item.Drive",
3297 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003298
Ed Tanousc1e219d2023-06-07 10:34:33 -07003299 dbus::utility::getSubTreePaths(
3300 "/", 0, inventoryForSystems,
3301 [health](const boost::system::error_code& ec,
3302 const std::vector<std::string>& resp) {
3303 if (ec)
3304 {
3305 // no inventory
3306 return;
3307 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003308
Ed Tanousc1e219d2023-06-07 10:34:33 -07003309 health->inventory = resp;
3310 });
3311 health->populate();
3312 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003313
Ed Tanousc1e219d2023-06-07 10:34:33 -07003314 getMainChassisId(asyncResp,
3315 [](const std::string& chassisId,
3316 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3317 nlohmann::json::array_t chassisArray;
3318 nlohmann::json& chassis = chassisArray.emplace_back();
3319 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3320 chassisId);
3321 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3322 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003323
Ed Tanousc1e219d2023-06-07 10:34:33 -07003324 getLocationIndicatorActive(asyncResp);
3325 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3326 getIndicatorLedState(asyncResp);
3327 getComputerSystem(asyncResp, health);
3328 getHostState(asyncResp);
3329 getBootProperties(asyncResp);
3330 getBootProgress(asyncResp);
3331 getBootProgressLastStateTime(asyncResp);
3332 pcie_util::getPCIeDeviceList(asyncResp, "PCIeDevices");
3333 getHostWatchdogTimer(asyncResp);
3334 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003335 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003336 getAutomaticRetryPolicy(asyncResp);
3337 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003338#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003339 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003340#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003341 getTrustedModuleRequiredToBoot(asyncResp);
3342 getPowerMode(asyncResp);
3343 getIdlePowerSaver(asyncResp);
3344}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003345
Ed Tanousc1e219d2023-06-07 10:34:33 -07003346inline void handleComputerSystemPatch(
3347 crow::App& app, const crow::Request& req,
3348 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3349 const std::string& systemName)
3350{
3351 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3352 {
3353 return;
3354 }
3355 if constexpr (bmcwebEnableMultiHost)
3356 {
3357 // Option currently returns no systems. TBD
3358 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3359 systemName);
3360 return;
3361 }
3362 if (systemName != "system")
3363 {
3364 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3365 systemName);
3366 return;
3367 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003368
Ed Tanousc1e219d2023-06-07 10:34:33 -07003369 asyncResp->res.addHeader(
3370 boost::beast::http::field::link,
3371 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003372
Ed Tanousc1e219d2023-06-07 10:34:33 -07003373 std::optional<bool> locationIndicatorActive;
3374 std::optional<std::string> indicatorLed;
3375 std::optional<std::string> assetTag;
3376 std::optional<std::string> powerRestorePolicy;
3377 std::optional<std::string> powerMode;
3378 std::optional<bool> wdtEnable;
3379 std::optional<std::string> wdtTimeOutAction;
3380 std::optional<std::string> bootSource;
3381 std::optional<std::string> bootType;
3382 std::optional<std::string> bootEnable;
3383 std::optional<std::string> bootAutomaticRetry;
3384 std::optional<uint32_t> bootAutomaticRetryAttempts;
3385 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003386 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003387 std::optional<bool> ipsEnable;
3388 std::optional<uint8_t> ipsEnterUtil;
3389 std::optional<uint64_t> ipsEnterTime;
3390 std::optional<uint8_t> ipsExitUtil;
3391 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003392
Ed Tanousc1e219d2023-06-07 10:34:33 -07003393 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003394 if (!json_util::readJsonPatch(
3395 req, asyncResp->res,
3396 "IndicatorLED", indicatorLed,
3397 "LocationIndicatorActive", locationIndicatorActive,
3398 "AssetTag", assetTag,
3399 "PowerRestorePolicy", powerRestorePolicy,
3400 "PowerMode", powerMode,
3401 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3402 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3403 "Boot/BootSourceOverrideTarget", bootSource,
3404 "Boot/BootSourceOverrideMode", bootType,
3405 "Boot/BootSourceOverrideEnabled", bootEnable,
3406 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003407 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003408 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003409 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003410 "IdlePowerSaver/Enabled", ipsEnable,
3411 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3412 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3413 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3414 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3415 {
3416 return;
3417 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003418 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003419
Ed Tanousc1e219d2023-06-07 10:34:33 -07003420 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003421
Ed Tanousc1e219d2023-06-07 10:34:33 -07003422 if (assetTag)
3423 {
3424 setAssetTag(asyncResp, *assetTag);
3425 }
James Feistb49ac872019-05-21 15:12:01 -07003426
Ed Tanousc1e219d2023-06-07 10:34:33 -07003427 if (wdtEnable || wdtTimeOutAction)
3428 {
3429 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3430 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003431
Ed Tanousc1e219d2023-06-07 10:34:33 -07003432 if (bootSource || bootType || bootEnable)
3433 {
3434 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3435 }
3436 if (bootAutomaticRetry)
3437 {
3438 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3439 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003440
Ed Tanousc1e219d2023-06-07 10:34:33 -07003441 if (bootAutomaticRetryAttempts)
3442 {
3443 setAutomaticRetryAttempts(asyncResp,
3444 bootAutomaticRetryAttempts.value());
3445 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003446
Ed Tanousc1e219d2023-06-07 10:34:33 -07003447 if (bootTrustedModuleRequired)
3448 {
3449 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3450 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003451
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003452 if (stopBootOnFault)
3453 {
3454 setStopBootOnFault(asyncResp, *stopBootOnFault);
3455 }
3456
Ed Tanousc1e219d2023-06-07 10:34:33 -07003457 if (locationIndicatorActive)
3458 {
3459 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3460 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003461
Ed Tanousc1e219d2023-06-07 10:34:33 -07003462 // TODO (Gunnar): Remove IndicatorLED after enough time has
3463 // passed
3464 if (indicatorLed)
3465 {
3466 setIndicatorLedState(asyncResp, *indicatorLed);
3467 asyncResp->res.addHeader(boost::beast::http::field::warning,
3468 "299 - \"IndicatorLED is deprecated. Use "
3469 "LocationIndicatorActive instead.\"");
3470 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003471
Ed Tanousc1e219d2023-06-07 10:34:33 -07003472 if (powerRestorePolicy)
3473 {
3474 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3475 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003476
Ed Tanousc1e219d2023-06-07 10:34:33 -07003477 if (powerMode)
3478 {
3479 setPowerMode(asyncResp, *powerMode);
3480 }
Chris Cain37bbf982021-09-20 10:53:09 -05003481
Ed Tanousc1e219d2023-06-07 10:34:33 -07003482 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3483 {
3484 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3485 ipsExitUtil, ipsExitTime);
3486 }
3487}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303488
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003489inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003490 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003491 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003492 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003493{
3494 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3495 {
3496 return;
3497 }
3498 asyncResp->res.addHeader(
3499 boost::beast::http::field::link,
3500 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3501}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003502inline void handleSystemCollectionResetActionGet(
3503 crow::App& app, const crow::Request& req,
3504 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3505 const std::string& systemName)
3506{
3507 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3508 {
3509 return;
3510 }
3511 if constexpr (bmcwebEnableMultiHost)
3512 {
3513 // Option currently returns no systems. TBD
3514 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3515 systemName);
3516 return;
3517 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003518
Ed Tanousc1e219d2023-06-07 10:34:33 -07003519 if (systemName == "hypervisor")
3520 {
3521 handleHypervisorResetActionGet(asyncResp);
3522 return;
3523 }
3524
3525 if (systemName != "system")
3526 {
3527 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3528 systemName);
3529 return;
3530 }
3531
3532 asyncResp->res.addHeader(
3533 boost::beast::http::field::link,
3534 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3535
3536 asyncResp->res.jsonValue["@odata.id"] =
3537 "/redfish/v1/Systems/system/ResetActionInfo";
3538 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3539 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3540 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3541
3542 nlohmann::json::array_t parameters;
3543 nlohmann::json::object_t parameter;
3544
3545 parameter["Name"] = "ResetType";
3546 parameter["Required"] = true;
3547 parameter["DataType"] = "String";
3548 nlohmann::json::array_t allowableValues;
3549 allowableValues.emplace_back("On");
3550 allowableValues.emplace_back("ForceOff");
3551 allowableValues.emplace_back("ForceOn");
3552 allowableValues.emplace_back("ForceRestart");
3553 allowableValues.emplace_back("GracefulRestart");
3554 allowableValues.emplace_back("GracefulShutdown");
3555 allowableValues.emplace_back("PowerCycle");
3556 allowableValues.emplace_back("Nmi");
3557 parameter["AllowableValues"] = std::move(allowableValues);
3558 parameters.emplace_back(std::move(parameter));
3559
3560 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3561}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303562/**
3563 * SystemResetActionInfo derived class for delivering Computer Systems
3564 * ResetType AllowableValues using ResetInfo schema.
3565 */
Ed Tanous100afe52023-06-07 13:30:46 -07003566inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303567{
Ed Tanous100afe52023-06-07 13:30:46 -07003568 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3569 .privileges(redfish::privileges::headComputerSystemCollection)
3570 .methods(boost::beast::http::verb::head)(
3571 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3572
3573 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3574 .privileges(redfish::privileges::getComputerSystemCollection)
3575 .methods(boost::beast::http::verb::get)(
3576 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3577
3578 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3579 .privileges(redfish::privileges::headComputerSystem)
3580 .methods(boost::beast::http::verb::head)(
3581 std::bind_front(handleComputerSystemHead, std::ref(app)));
3582
3583 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3584 .privileges(redfish::privileges::getComputerSystem)
3585 .methods(boost::beast::http::verb::get)(
3586 std::bind_front(handleComputerSystemGet, std::ref(app)));
3587
3588 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3589 .privileges(redfish::privileges::patchComputerSystem)
3590 .methods(boost::beast::http::verb::patch)(
3591 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3592
3593 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3594 .privileges(redfish::privileges::postComputerSystem)
3595 .methods(boost::beast::http::verb::post)(std::bind_front(
3596 handleComputerSystemResetActionPost, std::ref(app)));
3597
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003598 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003599 .privileges(redfish::privileges::headActionInfo)
3600 .methods(boost::beast::http::verb::head)(std::bind_front(
3601 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003602 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003603 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003604 .methods(boost::beast::http::verb::get)(std::bind_front(
3605 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003606}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003607} // namespace redfish