blob: 272a24b65a1618ebf4111371f6e75f5d0a491dd3 [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"
Andrew Geissler33e1f122024-02-26 21:10:16 -060024#include "generated/enums/resource.hpp"
James Feistb49ac872019-05-21 15:12:01 -070025#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060026#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080027#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070028#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080029#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080030#include "registries/privilege_registry.hpp"
31#include "utils/dbus_utils.hpp"
32#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050033#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080034#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070035#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080036
Andrew Geisslerfc903b32023-05-31 14:15:42 -040037#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070038#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080039#include <boost/system/error_code.hpp>
Andrew Geissler33e1f122024-02-26 21:10:16 -060040#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070041#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070042#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040043#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020044#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050045
George Liu7a1dbc42022-12-07 16:03:22 +080046#include <array>
Andrew Geissler33e1f122024-02-26 21:10:16 -060047#include <memory>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060048#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080049#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080050#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060051#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020052
Ed Tanous1abe55e2018-09-05 08:30:59 -070053namespace redfish
54{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020055
Abhishek Patel5c3e9272021-06-24 10:11:33 -050056const static std::array<std::pair<std::string_view, std::string_view>, 2>
57 protocolToDBusForSystems{
58 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
59
Alpana Kumari9d3ae102019-04-12 06:49:32 -050060/**
61 * @brief Updates the Functional State of DIMMs
62 *
Ed Tanousac106bf2023-06-07 09:24:59 -070063 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050064 * @param[in] dimmState Dimm's Functional state, true/false
65 *
66 * @return None.
67 */
zhanghch058d1b46d2021-04-01 11:18:24 +080068inline void
Ed Tanousac106bf2023-06-07 09:24:59 -070069 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070070 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050071{
Ed Tanous62598e32023-07-17 17:06:25 -070072 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050073
Gunnar Mills4e0453b2020-07-08 14:00:30 -050074 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050075 // Update STATE only if previous State was DISABLED and current Dimm is
76 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070077 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070078 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050079 if (prevMemSummary == "Disabled")
80 {
Ed Tanouse05aec52022-01-25 10:28:56 -080081 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050082 {
Ed Tanousac106bf2023-06-07 09:24:59 -070083 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050084 "Enabled";
85 }
86 }
87}
88
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050090 * @brief Update "ProcessorSummary" "Status" "State" based on
91 * CPU Functional State
92 *
Ed Tanousac106bf2023-06-07 09:24:59 -070093 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050094 * @param[in] cpuFunctionalState is CPU functional true/false
95 *
96 * @return None.
97 */
Ed Tanousac106bf2023-06-07 09:24:59 -070098inline void modifyCpuFunctionalState(
99 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500100{
Ed Tanous62598e32023-07-17 17:06:25 -0700101 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500102
Ed Tanous02cad962022-06-30 16:50:15 -0700103 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700104 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500105
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500106 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500107 // Update STATE only if previous State was Non_Functional and current CPU is
108 // Functional.
109 if (prevProcState == "Disabled")
110 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800111 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500112 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700113 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114 "Enabled";
115 }
116 }
117}
118
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500119/*
120 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
121 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700122 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500123 * @param[in] cpuPresenceState CPU present or not
124 *
125 * @return None.
126 */
127inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700128 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500129 bool isCpuPresent)
130{
Ed Tanous62598e32023-07-17 17:06:25 -0700131 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500132
133 if (isCpuPresent)
134 {
135 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700136 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500137 auto* procCountPtr =
138 procCount.get_ptr<nlohmann::json::number_integer_t*>();
139 if (procCountPtr != nullptr)
140 {
141 // shouldn't be possible to be nullptr
142 *procCountPtr += 1;
143 }
144 }
145}
146
Ali Ahmed382d6472021-09-03 16:53:53 -0500147inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500149 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500151{
Ed Tanous62598e32023-07-17 17:06:25 -0700152 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500153
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200154 // TODO: Get Model
155
156 const uint16_t* coreCount = nullptr;
157
158 const bool success = sdbusplus::unpackPropertiesNoThrow(
159 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
160
161 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500162 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700163 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200164 return;
165 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500166
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200167 if (coreCount != nullptr)
168 {
169 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700170 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200171 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500172
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200173 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500174 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200175 coreCountJson = *coreCount;
176 }
177 else
178 {
179 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500180 }
181 }
182}
183
184/*
185 * @brief Get ProcessorSummary fields
186 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500188 * @param[in] service dbus service for Cpu Information
189 * @param[in] path dbus path for Cpu
190 *
191 * @return None.
192 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700193inline void
194 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500196{
Ed Tanousac106bf2023-06-07 09:24:59 -0700197 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500199 if (ec3)
200 {
Ed Tanous62598e32023-07-17 17:06:25 -0700201 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500202 return;
203 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700204 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500205 };
206
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500207 // Get the Presence of CPU
208 sdbusplus::asio::getProperty<bool>(
209 *crow::connections::systemBus, service, path,
210 "xyz.openbmc_project.Inventory.Item", "Present",
211 std::move(getCpuPresenceState));
212
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200213 sdbusplus::asio::getAllProperties(
214 *crow::connections::systemBus, service, path,
215 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700216 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800217 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800218 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700219 if (ec2)
220 {
Ed Tanous62598e32023-07-17 17:06:25 -0700221 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700222 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700223 return;
224 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700225 getProcessorProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500226 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500227}
228
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500229/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500230 * @brief processMemoryProperties fields
231 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700232 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500233 * @param[in] DBUS properties for memory
234 *
235 * @return None.
236 */
237inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700238 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500239 const dbus::utility::DBusPropertiesMap& properties)
240{
Ed Tanous62598e32023-07-17 17:06:25 -0700241 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500242
243 if (properties.empty())
244 {
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500245 return;
246 }
247
248 const size_t* memorySizeInKB = nullptr;
249
250 const bool success = sdbusplus::unpackPropertiesNoThrow(
251 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
252 memorySizeInKB);
253
254 if (!success)
255 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700256 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500257 return;
258 }
259
260 if (memorySizeInKB != nullptr)
261 {
262 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700263 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500264 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500265 if (preValue == nullptr)
266 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700267 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500268 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500269 }
270 else
271 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700272 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500273 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
274 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500275 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500276 }
277}
278
279/*
280 * @brief Get getMemorySummary fields
281 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700282 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500283 * @param[in] service dbus service for memory Information
284 * @param[in] path dbus path for memory
285 *
286 * @return None.
287 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700288inline void
289 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
290 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500291{
292 sdbusplus::asio::getAllProperties(
293 *crow::connections::systemBus, service, path,
294 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700295 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500296 path](const boost::system::error_code& ec2,
297 const dbus::utility::DBusPropertiesMap& properties) {
298 if (ec2)
299 {
Ed Tanous62598e32023-07-17 17:06:25 -0700300 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -0700301 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500302 return;
303 }
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500304 processMemoryProperties(asyncResp, properties);
Patrick Williams5a39f772023-10-20 11:20:21 -0500305 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500306}
307
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500308inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
309 const boost::system::error_code& ec,
310 const dbus::utility::DBusPropertiesMap& properties)
311{
312 if (ec)
313 {
314 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
315 messages::internalError(asyncResp->res);
316 return;
317 }
318 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
319
320 const std::string* uUID = nullptr;
321
322 const bool success = sdbusplus::unpackPropertiesNoThrow(
323 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
324
325 if (!success)
326 {
327 messages::internalError(asyncResp->res);
328 return;
329 }
330
331 if (uUID != nullptr)
332 {
333 std::string valueStr = *uUID;
334 if (valueStr.size() == 32)
335 {
336 valueStr.insert(8, 1, '-');
337 valueStr.insert(13, 1, '-');
338 valueStr.insert(18, 1, '-');
339 valueStr.insert(23, 1, '-');
340 }
341 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
342 asyncResp->res.jsonValue["UUID"] = valueStr;
343 }
344}
345
346inline void
347 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
348 const boost::system::error_code& ec,
349 const dbus::utility::DBusPropertiesMap& propertiesList)
350{
351 if (ec)
352 {
353 // doesn't have to include this
354 // interface
355 return;
356 }
357 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
358
359 const std::string* partNumber = nullptr;
360 const std::string* serialNumber = nullptr;
361 const std::string* manufacturer = nullptr;
362 const std::string* model = nullptr;
363 const std::string* subModel = nullptr;
364
365 const bool success = sdbusplus::unpackPropertiesNoThrow(
366 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
367 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
368 "Model", model, "SubModel", subModel);
369
370 if (!success)
371 {
372 messages::internalError(asyncResp->res);
373 return;
374 }
375
376 if (partNumber != nullptr)
377 {
378 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
379 }
380
381 if (serialNumber != nullptr)
382 {
383 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
384 }
385
386 if (manufacturer != nullptr)
387 {
388 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
389 }
390
391 if (model != nullptr)
392 {
393 asyncResp->res.jsonValue["Model"] = *model;
394 }
395
396 if (subModel != nullptr)
397 {
398 asyncResp->res.jsonValue["SubModel"] = *subModel;
399 }
400
401 // Grab the bios version
402 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
403 "BiosVersion", false);
404}
405
406inline void
407 afterGetAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
408 const boost::system::error_code& ec,
409 const std::string& value)
410{
411 if (ec)
412 {
413 // doesn't have to include this
414 // interface
415 return;
416 }
417
418 asyncResp->res.jsonValue["AssetTag"] = value;
419}
420
421inline void afterSystemGetSubTree(
422 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500423 const boost::system::error_code& ec,
424 const dbus::utility::MapperGetSubTreeResponse& subtree)
425{
426 if (ec)
427 {
428 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
429 messages::internalError(asyncResp->res);
430 return;
431 }
432 // Iterate over all retrieved ObjectPaths.
433 for (const std::pair<
434 std::string,
435 std::vector<std::pair<std::string, std::vector<std::string>>>>&
436 object : subtree)
437 {
438 const std::string& path = object.first;
439 BMCWEB_LOG_DEBUG("Got path: {}", path);
440 const std::vector<std::pair<std::string, std::vector<std::string>>>&
441 connectionNames = object.second;
442 if (connectionNames.empty())
443 {
444 continue;
445 }
446
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500447 // This is not system, so check if it's cpu, dimm, UUID or
448 // BiosVer
449 for (const auto& connection : connectionNames)
450 {
451 for (const auto& interfaceName : connection.second)
452 {
453 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
454 {
455 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
456
457 getMemorySummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500458 }
459 else if (interfaceName ==
460 "xyz.openbmc_project.Inventory.Item.Cpu")
461 {
462 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
463
464 getProcessorSummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500465 }
466 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
467 {
468 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
469
470 sdbusplus::asio::getAllProperties(
471 *crow::connections::systemBus, connection.first, path,
472 "xyz.openbmc_project.Common.UUID",
473 [asyncResp](const boost::system::error_code& ec3,
474 const dbus::utility::DBusPropertiesMap&
475 properties) {
476 afterGetUUID(asyncResp, ec3, properties);
477 });
478 }
479 else if (interfaceName ==
480 "xyz.openbmc_project.Inventory.Item.System")
481 {
482 sdbusplus::asio::getAllProperties(
483 *crow::connections::systemBus, connection.first, path,
484 "xyz.openbmc_project.Inventory.Decorator.Asset",
485 [asyncResp](const boost::system::error_code& ec3,
486 const dbus::utility::DBusPropertiesMap&
487 properties) {
488 afterGetInventory(asyncResp, ec3, properties);
489 });
490
491 sdbusplus::asio::getProperty<std::string>(
492 *crow::connections::systemBus, connection.first, path,
493 "xyz.openbmc_project.Inventory.Decorator."
494 "AssetTag",
495 "AssetTag",
496 std::bind_front(afterGetAssetTag, asyncResp));
497 }
498 }
499 }
500 }
501}
502
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500503/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700504 * @brief Retrieves computer system properties over dbus
505 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700506 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ed Tanous6c34de42018-08-29 13:37:36 -0700507 *
508 * @return None.
509 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700510inline void
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500511 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700512{
Ed Tanous62598e32023-07-17 17:06:25 -0700513 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800514 constexpr std::array<std::string_view, 5> interfaces = {
515 "xyz.openbmc_project.Inventory.Decorator.Asset",
516 "xyz.openbmc_project.Inventory.Item.Cpu",
517 "xyz.openbmc_project.Inventory.Item.Dimm",
518 "xyz.openbmc_project.Inventory.Item.System",
519 "xyz.openbmc_project.Common.UUID",
520 };
521 dbus::utility::getSubTree(
522 "/xyz/openbmc_project/inventory", 0, interfaces,
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500523 std::bind_front(afterSystemGetSubTree, asyncResp));
Ed Tanous6c34de42018-08-29 13:37:36 -0700524}
525
526/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700527 * @brief Retrieves host state properties over dbus
528 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700529 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700530 *
531 * @return None.
532 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700533inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700534{
Ed Tanous62598e32023-07-17 17:06:25 -0700535 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700536 sdbusplus::asio::getProperty<std::string>(
537 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
538 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
539 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700540 [asyncResp](const boost::system::error_code& ec,
541 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700542 if (ec)
543 {
544 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700545 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700546 // Service not available, no error, just don't return
547 // host state info
Ed Tanous62598e32023-07-17 17:06:25 -0700548 BMCWEB_LOG_DEBUG("Service not available {}", ec);
Ed Tanous6c34de42018-08-29 13:37:36 -0700549 return;
550 }
Ed Tanous62598e32023-07-17 17:06:25 -0700551 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700552 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700553 return;
554 }
Ed Tanous66173382018-08-15 18:20:59 -0700555
Ed Tanous62598e32023-07-17 17:06:25 -0700556 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
Ed Tanous002d39b2022-05-31 08:59:27 -0700557 // Verify Host State
558 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
559 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700560 asyncResp->res.jsonValue["PowerState"] = "On";
561 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700562 }
563 else if (hostState ==
564 "xyz.openbmc_project.State.Host.HostState.Quiesced")
565 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700566 asyncResp->res.jsonValue["PowerState"] = "On";
567 asyncResp->res.jsonValue["Status"]["State"] = "Quiesced";
Ed Tanous002d39b2022-05-31 08:59:27 -0700568 }
569 else if (hostState ==
570 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
571 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700572 asyncResp->res.jsonValue["PowerState"] = "On";
573 asyncResp->res.jsonValue["Status"]["State"] = "InTest";
Ed Tanous002d39b2022-05-31 08:59:27 -0700574 }
575 else if (
576 hostState ==
577 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
578 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700579 asyncResp->res.jsonValue["PowerState"] = "PoweringOn";
580 asyncResp->res.jsonValue["Status"]["State"] = "Starting";
Ed Tanous002d39b2022-05-31 08:59:27 -0700581 }
582 else if (hostState ==
583 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
584 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700585 asyncResp->res.jsonValue["PowerState"] = "PoweringOff";
586 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700587 }
588 else
589 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700590 asyncResp->res.jsonValue["PowerState"] = "Off";
591 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -0700592 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500593 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700594}
595
596/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500597 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530598 *
599 * @param[in] dbusSource The boot source in DBUS speak.
600 *
601 * @return Returns as a string, the boot source in Redfish terms. If translation
602 * cannot be done, returns an empty string.
603 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000604inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530605{
606 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
607 {
608 return "None";
609 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700610 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530611 {
612 return "Hdd";
613 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700614 if (dbusSource ==
615 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530616 {
617 return "Cd";
618 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700619 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530620 {
621 return "Pxe";
622 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700623 if (dbusSource ==
624 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700625 {
626 return "Usb";
627 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700628 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530629}
630
631/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300632 * @brief Translates boot type DBUS property value to redfish.
633 *
634 * @param[in] dbusType The boot type in DBUS speak.
635 *
636 * @return Returns as a string, the boot type in Redfish terms. If translation
637 * cannot be done, returns an empty string.
638 */
639inline std::string dbusToRfBootType(const std::string& dbusType)
640{
641 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
642 {
643 return "Legacy";
644 }
645 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
646 {
647 return "UEFI";
648 }
649 return "";
650}
651
652/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500653 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530654 *
655 * @param[in] dbusMode The boot mode in DBUS speak.
656 *
657 * @return Returns as a string, the boot mode in Redfish terms. If translation
658 * cannot be done, returns an empty string.
659 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000660inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530661{
662 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
663 {
664 return "None";
665 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700666 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530667 {
668 return "Diags";
669 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700670 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530671 {
672 return "BiosSetup";
673 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700674 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530675}
676
677/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600678 * @brief Translates boot progress DBUS property value to redfish.
679 *
680 * @param[in] dbusBootProgress The boot progress in DBUS speak.
681 *
682 * @return Returns as a string, the boot progress in Redfish terms. If
683 * translation cannot be done, returns "None".
684 */
685inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
686{
687 // Now convert the D-Bus BootProgress to the appropriate Redfish
688 // enum
689 std::string rfBpLastState = "None";
690 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
691 "ProgressStages.Unspecified")
692 {
693 rfBpLastState = "None";
694 }
695 else if (dbusBootProgress ==
696 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
697 "PrimaryProcInit")
698 {
699 rfBpLastState = "PrimaryProcessorInitializationStarted";
700 }
701 else if (dbusBootProgress ==
702 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
703 "BusInit")
704 {
705 rfBpLastState = "BusInitializationStarted";
706 }
707 else if (dbusBootProgress ==
708 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
709 "MemoryInit")
710 {
711 rfBpLastState = "MemoryInitializationStarted";
712 }
713 else if (dbusBootProgress ==
714 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715 "SecondaryProcInit")
716 {
717 rfBpLastState = "SecondaryProcessorInitializationStarted";
718 }
719 else if (dbusBootProgress ==
720 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721 "PCIInit")
722 {
723 rfBpLastState = "PCIResourceConfigStarted";
724 }
725 else if (dbusBootProgress ==
726 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727 "SystemSetup")
728 {
729 rfBpLastState = "SetupEntered";
730 }
731 else if (dbusBootProgress ==
732 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733 "SystemInitComplete")
734 {
735 rfBpLastState = "SystemHardwareInitializationComplete";
736 }
737 else if (dbusBootProgress ==
738 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739 "OSStart")
740 {
741 rfBpLastState = "OSBootStarted";
742 }
743 else if (dbusBootProgress ==
744 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745 "OSRunning")
746 {
747 rfBpLastState = "OSRunning";
748 }
749 else
750 {
Ed Tanous62598e32023-07-17 17:06:25 -0700751 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600752 // Just return the default
753 }
754 return rfBpLastState;
755}
756
757/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500758 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530759 *
760 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700761 * @param[out] bootSource The DBus source
762 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530763 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700764 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530765 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700766inline int
767 assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
768 const std::string& rfSource, std::string& bootSource,
769 std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530770{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300771 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
772 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700773
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530774 if (rfSource == "None")
775 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700776 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530777 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700778 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530779 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700780 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
781 }
782 else if (rfSource == "Hdd")
783 {
784 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
785 }
786 else if (rfSource == "Diags")
787 {
788 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
789 }
790 else if (rfSource == "Cd")
791 {
792 bootSource =
793 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
794 }
795 else if (rfSource == "BiosSetup")
796 {
797 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530798 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700799 else if (rfSource == "Usb")
800 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700801 bootSource =
802 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700803 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530804 else
805 {
Ed Tanous62598e32023-07-17 17:06:25 -0700806 BMCWEB_LOG_DEBUG(
807 "Invalid property value for BootSourceOverrideTarget: {}",
808 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700809 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700810 "BootSourceTargetOverride");
811 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530812 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700813 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530814}
Ali Ahmed19817712021-06-29 17:01:52 -0500815
Andrew Geissler978b8802020-11-19 13:36:40 -0600816/**
817 * @brief Retrieves boot progress of the system
818 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700819 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600820 *
821 * @return None.
822 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700823inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600824{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700825 sdbusplus::asio::getProperty<std::string>(
826 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
827 "/xyz/openbmc_project/state/host0",
828 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700829 [asyncResp](const boost::system::error_code& ec,
830 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700831 if (ec)
832 {
833 // BootProgress is an optional object so just do nothing if
834 // not found
835 return;
836 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600837
Ed Tanous62598e32023-07-17 17:06:25 -0700838 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600839
Ed Tanousac106bf2023-06-07 09:24:59 -0700840 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700841 dbusToRfBootProgress(bootProgressStr);
Patrick Williams5a39f772023-10-20 11:20:21 -0500842 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600843}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530844
845/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000846 * @brief Retrieves boot progress Last Update of the system
847 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700848 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000849 *
850 * @return None.
851 */
852inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700853 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000854{
855 sdbusplus::asio::getProperty<uint64_t>(
856 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
857 "/xyz/openbmc_project/state/host0",
858 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700859 [asyncResp](const boost::system::error_code& ec,
860 const uint64_t lastStateTime) {
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000861 if (ec)
862 {
Ed Tanous62598e32023-07-17 17:06:25 -0700863 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000864 return;
865 }
866
867 // BootProgressLastUpdate is the last time the BootProgress property
868 // was updated. The time is the Epoch time, number of microseconds
869 // since 1 Jan 1970 00::00::00 UTC."
870 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
871 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
872
873 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -0700874 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000875 redfish::time_utils::getDateTimeUintUs(lastStateTime);
Patrick Williams5a39f772023-10-20 11:20:21 -0500876 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000877}
878
879/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300880 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300881 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700882 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300883 *
884 * @return None.
885 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300886
Ed Tanousac106bf2023-06-07 09:24:59 -0700887inline void
888 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300889{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700890 sdbusplus::asio::getProperty<std::string>(
891 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
892 "/xyz/openbmc_project/control/host0/boot",
893 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700894 [asyncResp](const boost::system::error_code& ec,
895 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700896 if (ec)
897 {
898 // not an error, don't have to have the interface
899 return;
900 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300901
Ed Tanous62598e32023-07-17 17:06:25 -0700902 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300903
Ed Tanousac106bf2023-06-07 09:24:59 -0700904 asyncResp->res
905 .jsonValue["Boot"]
906 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700907 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300908
Ed Tanous002d39b2022-05-31 08:59:27 -0700909 auto rfType = dbusToRfBootType(bootType);
910 if (rfType.empty())
911 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700912 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700913 return;
914 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300915
Ed Tanousac106bf2023-06-07 09:24:59 -0700916 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Patrick Williams5a39f772023-10-20 11:20:21 -0500917 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300918}
919
920/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300921 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530922 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700923 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530924 *
925 * @return None.
926 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300927
Ed Tanousac106bf2023-06-07 09:24:59 -0700928inline void
929 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530930{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700931 sdbusplus::asio::getProperty<std::string>(
932 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
933 "/xyz/openbmc_project/control/host0/boot",
934 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700935 [asyncResp](const boost::system::error_code& ec,
936 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700937 if (ec)
938 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -0500939 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700940 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700941 return;
942 }
943
Ed Tanous62598e32023-07-17 17:06:25 -0700944 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
Ed Tanous002d39b2022-05-31 08:59:27 -0700945
Ed Tanousac106bf2023-06-07 09:24:59 -0700946 asyncResp->res
Ed Tanous002d39b2022-05-31 08:59:27 -0700947 .jsonValue["Boot"]
948 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
949 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
950
951 if (bootModeStr !=
952 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
953 {
954 auto rfMode = dbusToRfBootMode(bootModeStr);
955 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530956 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700957 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
Ed Tanous002d39b2022-05-31 08:59:27 -0700958 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530959 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700960 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500961 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530962}
963
964/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300965 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530966 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700967 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530968 *
969 * @return None.
970 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300971
972inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700973 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700975 sdbusplus::asio::getProperty<std::string>(
976 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
977 "/xyz/openbmc_project/control/host0/boot",
978 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -0700979 [asyncResp](const boost::system::error_code& ec,
980 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700981 if (ec)
982 {
Nan Zhou5ef735c2022-06-22 05:24:21 +0000983 if (ec.value() == boost::asio::error::host_unreachable)
984 {
985 return;
986 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -0500987 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -0700988 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700989 return;
990 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530991
Ed Tanous62598e32023-07-17 17:06:25 -0700992 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530993
Ed Tanous002d39b2022-05-31 08:59:27 -0700994 auto rfSource = dbusToRfBootSource(bootSourceStr);
995 if (!rfSource.empty())
996 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700997 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
998 rfSource;
Ed Tanous002d39b2022-05-31 08:59:27 -0700999 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001000
Ed Tanous002d39b2022-05-31 08:59:27 -07001001 // Get BootMode as BootSourceOverrideTarget is constructed
1002 // from both BootSource and BootMode
Ed Tanousac106bf2023-06-07 09:24:59 -07001003 getBootOverrideMode(asyncResp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001004 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301005}
1006
1007/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001008 * @brief This functions abstracts all the logic behind getting a
1009 * "BootSourceOverrideEnabled" property from an overall boot override enable
1010 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301011 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001012 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301013 *
1014 * @return None.
1015 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301016
Ed Tanousac106bf2023-06-07 09:24:59 -07001017inline void processBootOverrideEnable(
1018 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1019 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001020{
1021 if (!bootOverrideEnableSetting)
1022 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001023 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1024 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001025 return;
1026 }
1027
1028 // If boot source override is enabled, we need to check 'one_time'
1029 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001030 sdbusplus::asio::getProperty<bool>(
1031 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1032 "/xyz/openbmc_project/control/host0/boot/one_time",
1033 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001034 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001035 if (ec)
1036 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001037 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001038 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001039 return;
1040 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301041
Ed Tanous002d39b2022-05-31 08:59:27 -07001042 if (oneTimeSetting)
1043 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001044 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1045 "Once";
Ed Tanous002d39b2022-05-31 08:59:27 -07001046 }
1047 else
1048 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001049 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001050 "Continuous";
1051 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001052 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301053}
1054
1055/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001056 * @brief Retrieves boot override enable over DBUS
1057 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001058 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001059 *
1060 * @return None.
1061 */
1062
1063inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001064 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001065{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001066 sdbusplus::asio::getProperty<bool>(
1067 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1068 "/xyz/openbmc_project/control/host0/boot",
1069 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001070 [asyncResp](const boost::system::error_code& ec,
1071 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001072 if (ec)
1073 {
Nan Zhou5ef735c2022-06-22 05:24:21 +00001074 if (ec.value() == boost::asio::error::host_unreachable)
1075 {
1076 return;
1077 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001078 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001079 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001080 return;
1081 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001082
Ed Tanousac106bf2023-06-07 09:24:59 -07001083 processBootOverrideEnable(asyncResp, bootOverrideEnable);
Patrick Williams5a39f772023-10-20 11:20:21 -05001084 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001085}
1086
1087/**
1088 * @brief Retrieves boot source override properties
1089 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001090 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001091 *
1092 * @return None.
1093 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001094inline void
1095 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001096{
Ed Tanous62598e32023-07-17 17:06:25 -07001097 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001098
Ed Tanousac106bf2023-06-07 09:24:59 -07001099 getBootOverrideSource(asyncResp);
1100 getBootOverrideType(asyncResp);
1101 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001102}
1103
1104/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001105 * @brief Retrieves the Last Reset Time
1106 *
1107 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1108 * and power off. Even though this is the "system" Redfish object look at the
1109 * chassis D-Bus interface for the LastStateChangeTime since this has the
1110 * last power operation time.
1111 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001112 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001113 *
1114 * @return None.
1115 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001116inline void
1117 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001118{
Ed Tanous62598e32023-07-17 17:06:25 -07001119 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001120
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001121 sdbusplus::asio::getProperty<uint64_t>(
1122 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1123 "/xyz/openbmc_project/state/chassis0",
1124 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001125 [asyncResp](const boost::system::error_code& ec,
1126 uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001127 if (ec)
1128 {
Ed Tanous62598e32023-07-17 17:06:25 -07001129 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001130 return;
1131 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001132
Ed Tanous002d39b2022-05-31 08:59:27 -07001133 // LastStateChangeTime is epoch time, in milliseconds
1134 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1135 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001136
Ed Tanous002d39b2022-05-31 08:59:27 -07001137 // Convert to ISO 8601 standard
Ed Tanousac106bf2023-06-07 09:24:59 -07001138 asyncResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001139 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Patrick Williams5a39f772023-10-20 11:20:21 -05001140 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001141}
1142
1143/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001144 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1145 *
1146 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1147 * corresponding property "AttemptsLeft" that keeps track of the amount of
1148 * automatic retry attempts left are hosted in phosphor-state-manager through
1149 * dbus.
1150 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001151 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001152 *
1153 * @return None.
1154 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001155inline void getAutomaticRebootAttempts(
1156 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001157{
Ed Tanous62598e32023-07-17 17:06:25 -07001158 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001159
1160 sdbusplus::asio::getAllProperties(
1161 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1162 "/xyz/openbmc_project/state/host0",
1163 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001164 [asyncResp{asyncResp}](
1165 const boost::system::error_code& ec,
1166 const dbus::utility::DBusPropertiesMap& propertiesList) {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001167 if (ec)
1168 {
1169 if (ec.value() != EBADR)
1170 {
Ed Tanous62598e32023-07-17 17:06:25 -07001171 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001172 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001173 }
1174 return;
1175 }
1176
1177 const uint32_t* attemptsLeft = nullptr;
1178 const uint32_t* retryAttempts = nullptr;
1179
1180 const bool success = sdbusplus::unpackPropertiesNoThrow(
1181 dbus_utils::UnpackErrorPrinter(), propertiesList, "AttemptsLeft",
1182 attemptsLeft, "RetryAttempts", retryAttempts);
1183
1184 if (!success)
1185 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001186 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001187 return;
1188 }
1189
1190 if (attemptsLeft != nullptr)
1191 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001192 asyncResp->res
1193 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001194 *attemptsLeft;
1195 }
1196
1197 if (retryAttempts != nullptr)
1198 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001199 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
Corey Hardesty797d5da2022-04-26 17:54:52 +08001200 *retryAttempts;
1201 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001202 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001203}
1204
1205/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001206 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1207 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001208 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001209 *
1210 * @return None.
1211 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001212inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001213 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001214{
Ed Tanous62598e32023-07-17 17:06:25 -07001215 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001216
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001217 sdbusplus::asio::getProperty<bool>(
1218 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1219 "/xyz/openbmc_project/control/host0/auto_reboot",
1220 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001221 [asyncResp](const boost::system::error_code& ec,
1222 bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001223 if (ec)
1224 {
Corey Hardesty797d5da2022-04-26 17:54:52 +08001225 if (ec.value() != EBADR)
1226 {
Ed Tanous62598e32023-07-17 17:06:25 -07001227 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001228 messages::internalError(asyncResp->res);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001229 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001230 return;
1231 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001232
Ed Tanous62598e32023-07-17 17:06:25 -07001233 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
Ed Tanous002d39b2022-05-31 08:59:27 -07001234 if (autoRebootEnabled)
1235 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001236 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001237 "RetryAttempts";
Ed Tanous002d39b2022-05-31 08:59:27 -07001238 }
1239 else
1240 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001241 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1242 "Disabled";
Ed Tanous002d39b2022-05-31 08:59:27 -07001243 }
Ed Tanousac106bf2023-06-07 09:24:59 -07001244 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001245
Ed Tanous002d39b2022-05-31 08:59:27 -07001246 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1247 // and RetryAttempts. OpenBMC only supports Disabled and
1248 // RetryAttempts.
Ed Tanousac106bf2023-06-07 09:24:59 -07001249 asyncResp->res
1250 .jsonValue["Boot"]["AutomaticRetryConfig@Redfish.AllowableValues"] =
1251 {"Disabled", "RetryAttempts"};
Patrick Williams5a39f772023-10-20 11:20:21 -05001252 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001253}
1254
1255/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001256 * @brief Sets RetryAttempts
1257 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001258 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001259 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1260 *
1261 *@return None.
1262 */
1263
Ed Tanousac106bf2023-06-07 09:24:59 -07001264inline void setAutomaticRetryAttempts(
1265 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1266 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001267{
Ed Tanous62598e32023-07-17 17:06:25 -07001268 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
George Liu9ae226f2023-06-21 17:56:46 +08001269 sdbusplus::asio::setProperty(
1270 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1271 "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001272 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
George Liu9ae226f2023-06-21 17:56:46 +08001273 retryAttempts, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001274 if (ec)
1275 {
1276 BMCWEB_LOG_ERROR(
1277 "DBUS response error: Set setAutomaticRetryAttempts{}", ec);
1278 messages::internalError(asyncResp->res);
1279 return;
1280 }
1281 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001282}
1283
Ed Tanous8d69c662023-06-21 10:29:06 -07001284inline computer_system::PowerRestorePolicyTypes
1285 redfishPowerRestorePolicyFromDbus(std::string_view value)
1286{
1287 if (value ==
1288 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1289 {
1290 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1291 }
1292 if (value ==
1293 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1294 {
1295 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1296 }
1297 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001298 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001299 {
1300 return computer_system::PowerRestorePolicyTypes::LastState;
1301 }
1302 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1303 {
1304 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1305 }
1306 return computer_system::PowerRestorePolicyTypes::Invalid;
1307}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001308/**
George Liuc6a620f2020-04-10 17:18:11 +08001309 * @brief Retrieves power restore policy over DBUS.
1310 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001311 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001312 *
1313 * @return None.
1314 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001315inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001316 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001317{
Ed Tanous62598e32023-07-17 17:06:25 -07001318 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001319
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001320 sdbusplus::asio::getProperty<std::string>(
1321 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1322 "/xyz/openbmc_project/control/host0/power_restore_policy",
1323 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001324 [asyncResp](const boost::system::error_code& ec,
1325 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001326 if (ec)
1327 {
Ed Tanous62598e32023-07-17 17:06:25 -07001328 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001329 return;
1330 }
Ed Tanous8d69c662023-06-21 10:29:06 -07001331 computer_system::PowerRestorePolicyTypes restore =
1332 redfishPowerRestorePolicyFromDbus(policy);
1333 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
Ed Tanous002d39b2022-05-31 08:59:27 -07001334 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001335 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001336 return;
1337 }
George Liuc6a620f2020-04-10 17:18:11 +08001338
Ed Tanous8d69c662023-06-21 10:29:06 -07001339 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
Patrick Williams5a39f772023-10-20 11:20:21 -05001340 });
George Liuc6a620f2020-04-10 17:18:11 +08001341}
1342
1343/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001344 * @brief Stop Boot On Fault over DBUS.
1345 *
1346 * @param[in] asyncResp Shared pointer for generating response message.
1347 *
1348 * @return None.
1349 */
1350inline void
1351 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1352{
Ed Tanous62598e32023-07-17 17:06:25 -07001353 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001354
1355 sdbusplus::asio::getProperty<bool>(
1356 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1357 "/xyz/openbmc_project/logging/settings",
1358 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1359 [asyncResp](const boost::system::error_code& ec, bool value) {
1360 if (ec)
1361 {
1362 if (ec.value() != EBADR)
1363 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001364 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001365 messages::internalError(asyncResp->res);
1366 }
1367 return;
1368 }
1369
1370 if (value)
1371 {
1372 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "AnyFault";
1373 }
1374 else
1375 {
1376 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] = "Never";
1377 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001378 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001379}
1380
1381/**
Ali Ahmed19817712021-06-29 17:01:52 -05001382 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1383 * TPM is required for booting the host.
1384 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001385 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001386 *
1387 * @return None.
1388 */
1389inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001390 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001391{
Ed Tanous62598e32023-07-17 17:06:25 -07001392 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001393 constexpr std::array<std::string_view, 1> interfaces = {
1394 "xyz.openbmc_project.Control.TPM.Policy"};
1395 dbus::utility::getSubTree(
1396 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001397 [asyncResp](const boost::system::error_code& ec,
1398 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001399 if (ec)
1400 {
Ed Tanous62598e32023-07-17 17:06:25 -07001401 BMCWEB_LOG_DEBUG("DBUS response error on TPM.Policy GetSubTree{}",
1402 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07001403 // This is an optional D-Bus object so just return if
1404 // error occurs
1405 return;
1406 }
1407 if (subtree.empty())
1408 {
1409 // As noted above, this is an optional interface so just return
1410 // if there is no instance found
1411 return;
1412 }
1413
1414 /* When there is more than one TPMEnable object... */
1415 if (subtree.size() > 1)
1416 {
Ed Tanous62598e32023-07-17 17:06:25 -07001417 BMCWEB_LOG_DEBUG(
1418 "DBUS response has more than 1 TPM Enable object:{}",
1419 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001420 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001421 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001422 return;
1423 }
1424
1425 // Make sure the Dbus response map has a service and objectPath
1426 // field
1427 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1428 {
Ed Tanous62598e32023-07-17 17:06:25 -07001429 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001430 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001431 return;
1432 }
1433
1434 const std::string& path = subtree[0].first;
1435 const std::string& serv = subtree[0].second.begin()->first;
1436
1437 // Valid TPM Enable object found, now reading the current value
1438 sdbusplus::asio::getProperty<bool>(
1439 *crow::connections::systemBus, serv, path,
1440 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanousac106bf2023-06-07 09:24:59 -07001441 [asyncResp](const boost::system::error_code& ec2,
1442 bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001443 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001444 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001445 BMCWEB_LOG_ERROR("D-BUS response error on TPM.Policy Get{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001446 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001447 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001448 return;
1449 }
1450
Ed Tanous002d39b2022-05-31 08:59:27 -07001451 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001452 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001453 asyncResp->res
1454 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001455 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001456 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001457 else
1458 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001459 asyncResp->res
1460 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07001461 "Disabled";
1462 }
George Liue99073f2022-12-09 11:06:16 +08001463 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001464 });
Ali Ahmed19817712021-06-29 17:01:52 -05001465}
1466
1467/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001468 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1469 * TPM is required for booting the host.
1470 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001471 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001472 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1473 *
1474 * @return None.
1475 */
1476inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001477 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001478{
Ed Tanous62598e32023-07-17 17:06:25 -07001479 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001480 constexpr std::array<std::string_view, 1> interfaces = {
1481 "xyz.openbmc_project.Control.TPM.Policy"};
1482 dbus::utility::getSubTree(
1483 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001484 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001485 tpmRequired](const boost::system::error_code& ec,
1486 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001487 if (ec)
1488 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001489 BMCWEB_LOG_ERROR("DBUS response error on TPM.Policy GetSubTree{}",
Ed Tanous62598e32023-07-17 17:06:25 -07001490 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001491 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001492 return;
1493 }
1494 if (subtree.empty())
1495 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001496 messages::propertyValueNotInList(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07001497 "TrustedModuleRequiredToBoot");
1498 return;
1499 }
1500
1501 /* When there is more than one TPMEnable object... */
1502 if (subtree.size() > 1)
1503 {
Ed Tanous62598e32023-07-17 17:06:25 -07001504 BMCWEB_LOG_DEBUG(
1505 "DBUS response has more than 1 TPM Enable object:{}",
1506 subtree.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07001507 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001508 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001509 return;
1510 }
1511
1512 // Make sure the Dbus response map has a service and objectPath
1513 // field
1514 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1515 {
Ed Tanous62598e32023-07-17 17:06:25 -07001516 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001517 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001518 return;
1519 }
1520
1521 const std::string& path = subtree[0].first;
1522 const std::string& serv = subtree[0].second.begin()->first;
1523
1524 if (serv.empty())
1525 {
Ed Tanous62598e32023-07-17 17:06:25 -07001526 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001527 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001528 return;
1529 }
1530
1531 // Valid TPM Enable object found, now setting the value
George Liu9ae226f2023-06-21 17:56:46 +08001532 sdbusplus::asio::setProperty(
1533 *crow::connections::systemBus, serv, path,
1534 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable", tpmRequired,
Ed Tanousac106bf2023-06-07 09:24:59 -07001535 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001536 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001537 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001538 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07001539 "DBUS response error: Set TrustedModuleRequiredToBoot{}",
1540 ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001541 messages::internalError(asyncResp->res);
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001542 return;
1543 }
Ed Tanous62598e32023-07-17 17:06:25 -07001544 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot done.");
George Liue99073f2022-12-09 11:06:16 +08001545 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001546 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001547}
1548
1549/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301550 * @brief Sets boot properties into DBUS object(s).
1551 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001552 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001553 * @param[in] bootType The boot type to set.
1554 * @return Integer error code.
1555 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001556inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001557 const std::optional<std::string>& bootType)
1558{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001559 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001560
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001561 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001562 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001563 return;
1564 }
1565
1566 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001567 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001568 // Figure out which DBUS interface and property to use
1569 if (*bootType == "Legacy")
1570 {
1571 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1572 }
1573 else if (*bootType == "UEFI")
1574 {
1575 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1576 }
1577 else
1578 {
Ed Tanous62598e32023-07-17 17:06:25 -07001579 BMCWEB_LOG_DEBUG("Invalid property value for "
1580 "BootSourceOverrideMode: {}",
1581 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001582 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001583 "BootSourceOverrideMode");
1584 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001585 }
1586
1587 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001588 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001589
George Liu9ae226f2023-06-21 17:56:46 +08001590 sdbusplus::asio::setProperty(
1591 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1592 "/xyz/openbmc_project/control/host0/boot",
1593 "xyz.openbmc_project.Control.Boot.Type", "BootType", bootTypeStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001594 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001595 if (ec)
1596 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001597 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001598 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001599 messages::resourceNotFound(asyncResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001600 return;
1601 }
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001602 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001603 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001604 return;
1605 }
Ed Tanous62598e32023-07-17 17:06:25 -07001606 BMCWEB_LOG_DEBUG("Boot type update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001607 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001608}
1609
1610/**
1611 * @brief Sets boot properties into DBUS object(s).
1612 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001613 * @param[in] asyncResp Shared pointer for generating response
1614 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001615 * @param[in] bootType The boot type to set.
1616 * @return Integer error code.
1617 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001618inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001619 const std::optional<std::string>& bootEnable)
1620{
1621 if (!bootEnable)
1622 {
1623 return;
1624 }
1625 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001626 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001627
1628 bool bootOverrideEnable = false;
1629 bool bootOverridePersistent = false;
1630 // Figure out which DBUS interface and property to use
1631 if (*bootEnable == "Disabled")
1632 {
1633 bootOverrideEnable = false;
1634 }
1635 else if (*bootEnable == "Once")
1636 {
1637 bootOverrideEnable = true;
1638 bootOverridePersistent = false;
1639 }
1640 else if (*bootEnable == "Continuous")
1641 {
1642 bootOverrideEnable = true;
1643 bootOverridePersistent = true;
1644 }
1645 else
1646 {
Ed Tanous62598e32023-07-17 17:06:25 -07001647 BMCWEB_LOG_DEBUG(
1648 "Invalid property value for BootSourceOverrideEnabled: {}",
1649 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001650 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001651 "BootSourceOverrideEnabled");
1652 return;
1653 }
1654
1655 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001656 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001657
George Liu9ae226f2023-06-21 17:56:46 +08001658 sdbusplus::asio::setProperty(
1659 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1660 "/xyz/openbmc_project/control/host0/boot",
1661 "xyz.openbmc_project.Object.Enable", "Enabled", bootOverrideEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07001662 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001663 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001664 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001665 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07001666 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001667 return;
1668 }
Ed Tanous62598e32023-07-17 17:06:25 -07001669 BMCWEB_LOG_DEBUG("Boot override enable update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001670 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001671
1672 if (!bootOverrideEnable)
1673 {
1674 return;
1675 }
1676
1677 // In case boot override is enabled we need to set correct value for the
1678 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001679 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1680 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001681
George Liu9ae226f2023-06-21 17:56:46 +08001682 sdbusplus::asio::setProperty(
1683 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1684 "/xyz/openbmc_project/control/host0/boot/one_time",
1685 "xyz.openbmc_project.Object.Enable", "Enabled", !bootOverridePersistent,
Ed Tanousac106bf2023-06-07 09:24:59 -07001686 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001687 if (ec)
1688 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001689 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001690 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001691 return;
1692 }
Ed Tanous62598e32023-07-17 17:06:25 -07001693 BMCWEB_LOG_DEBUG("Boot one_time update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001694 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001695}
1696
1697/**
1698 * @brief Sets boot properties into DBUS object(s).
1699 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001700 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301701 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301702 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001703 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301704 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001705inline void
1706 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1707 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301708{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001709 std::string bootSourceStr;
1710 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001711
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001712 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301713 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001714 return;
1715 }
1716
1717 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001718 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001719 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001720 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1721 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001722 {
Ed Tanous62598e32023-07-17 17:06:25 -07001723 BMCWEB_LOG_DEBUG(
1724 "Invalid property value for BootSourceOverrideTarget: {}",
1725 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001726 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001727 "BootSourceTargetOverride");
1728 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001729 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301730
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001731 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001732 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1733 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001734
George Liu9ae226f2023-06-21 17:56:46 +08001735 sdbusplus::asio::setProperty(
1736 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1737 "/xyz/openbmc_project/control/host0/boot",
1738 "xyz.openbmc_project.Control.Boot.Source", "BootSource", bootSourceStr,
Ed Tanousac106bf2023-06-07 09:24:59 -07001739 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001740 if (ec)
1741 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001742 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001743 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001744 return;
1745 }
Ed Tanous62598e32023-07-17 17:06:25 -07001746 BMCWEB_LOG_DEBUG("Boot source update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001747 });
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001748
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",
1752 "xyz.openbmc_project.Control.Boot.Mode", "BootMode", bootModeStr,
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 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05001756 BMCWEB_LOG_ERROR("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 }
Ed Tanous62598e32023-07-17 17:06:25 -07001760 BMCWEB_LOG_DEBUG("Boot mode update done.");
Patrick Williams5a39f772023-10-20 11:20:21 -05001761 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001762}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001763
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001764/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001765 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301766 *
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 from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001769 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301770 * @param[in] bootEnable The boot override enable from incoming RF request.
1771 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001772 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301773 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001774
Ed Tanousac106bf2023-06-07 09:24:59 -07001775inline void
1776 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1777 const std::optional<std::string>& bootSource,
1778 const std::optional<std::string>& bootType,
1779 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301780{
Ed Tanous62598e32023-07-17 17:06:25 -07001781 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301782
Ed Tanousac106bf2023-06-07 09:24:59 -07001783 setBootModeOrSource(asyncResp, bootSource);
1784 setBootType(asyncResp, bootType);
1785 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301786}
1787
George Liuc6a620f2020-04-10 17:18:11 +08001788/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001789 * @brief Sets AssetTag
1790 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001791 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001792 * @param[in] assetTag "AssetTag" from request.
1793 *
1794 * @return None.
1795 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001796inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001797 const std::string& assetTag)
1798{
George Liue99073f2022-12-09 11:06:16 +08001799 constexpr std::array<std::string_view, 1> interfaces = {
1800 "xyz.openbmc_project.Inventory.Item.System"};
1801 dbus::utility::getSubTree(
1802 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001803 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001804 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001805 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001806 if (ec)
1807 {
Ed Tanous62598e32023-07-17 17:06:25 -07001808 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07001809 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001810 return;
1811 }
1812 if (subtree.empty())
1813 {
Ed Tanous62598e32023-07-17 17:06:25 -07001814 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001815 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001816 return;
1817 }
1818 // Assume only 1 system D-Bus object
1819 // Throw an error if there is more than 1
1820 if (subtree.size() > 1)
1821 {
Ed Tanous62598e32023-07-17 17:06:25 -07001822 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001823 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001824 return;
1825 }
1826 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1827 {
Ed Tanous62598e32023-07-17 17:06:25 -07001828 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001829 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001830 return;
1831 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001832
Ed Tanous002d39b2022-05-31 08:59:27 -07001833 const std::string& path = subtree[0].first;
1834 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001835
Ed Tanous002d39b2022-05-31 08:59:27 -07001836 if (service.empty())
1837 {
Ed Tanous62598e32023-07-17 17:06:25 -07001838 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07001839 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07001840 return;
1841 }
1842
George Liu9ae226f2023-06-21 17:56:46 +08001843 sdbusplus::asio::setProperty(
1844 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07001845 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
George Liu9ae226f2023-06-21 17:56:46 +08001846 assetTag, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001847 if (ec2)
1848 {
1849 BMCWEB_LOG_ERROR("D-Bus response error on AssetTag Set {}",
1850 ec2);
1851 messages::internalError(asyncResp->res);
1852 return;
1853 }
George Liue99073f2022-12-09 11:06:16 +08001854 });
Patrick Williams5a39f772023-10-20 11:20:21 -05001855 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001856}
1857
1858/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001859 * @brief Validate the specified stopBootOnFault is valid and return the
1860 * stopBootOnFault name associated with that string
1861 *
1862 * @param[in] stopBootOnFaultString String representing the desired
1863 * stopBootOnFault
1864 *
1865 * @return stopBootOnFault value or empty if incoming value is not valid
1866 */
1867inline std::optional<bool>
1868 validstopBootOnFault(const std::string& stopBootOnFaultString)
1869{
1870 if (stopBootOnFaultString == "AnyFault")
1871 {
1872 return true;
1873 }
1874
1875 if (stopBootOnFaultString == "Never")
1876 {
1877 return false;
1878 }
1879
1880 return std::nullopt;
1881}
1882
1883/**
1884 * @brief Sets stopBootOnFault
1885 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001886 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001887 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1888 *
1889 * @return None.
1890 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001891inline void
1892 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1893 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001894{
Ed Tanous62598e32023-07-17 17:06:25 -07001895 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001896
1897 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1898 if (!stopBootEnabled)
1899 {
Ed Tanous62598e32023-07-17 17:06:25 -07001900 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1901 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001902 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001903 "StopBootOnFault");
1904 return;
1905 }
1906
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001907 sdbusplus::asio::setProperty(
1908 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1909 "/xyz/openbmc_project/logging/settings",
1910 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1911 *stopBootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001912 if (ec)
1913 {
1914 if (ec.value() != EBADR)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001915 {
Patrick Williams5a39f772023-10-20 11:20:21 -05001916 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1917 messages::internalError(asyncResp->res);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001918 }
Patrick Williams5a39f772023-10-20 11:20:21 -05001919 return;
1920 }
1921 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001922}
1923
1924/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001925 * @brief Sets automaticRetry (Auto Reboot)
1926 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001927 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001928 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1929 *
1930 * @return None.
1931 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001932inline void
1933 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1934 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001935{
Ed Tanous62598e32023-07-17 17:06:25 -07001936 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001937
1938 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001939 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001940
1941 if (automaticRetryConfig == "Disabled")
1942 {
1943 autoRebootEnabled = false;
1944 }
1945 else if (automaticRetryConfig == "RetryAttempts")
1946 {
1947 autoRebootEnabled = true;
1948 }
1949 else
1950 {
Ed Tanous62598e32023-07-17 17:06:25 -07001951 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
1952 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07001953 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001954 "AutomaticRetryConfig");
1955 return;
1956 }
1957
George Liu9ae226f2023-06-21 17:56:46 +08001958 sdbusplus::asio::setProperty(
1959 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
Gunnar Mills69f35302020-05-17 16:06:31 -05001960 "/xyz/openbmc_project/control/host0/auto_reboot",
Gunnar Mills69f35302020-05-17 16:06:31 -05001961 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
George Liu9ae226f2023-06-21 17:56:46 +08001962 autoRebootEnabled, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05001963 if (ec)
1964 {
1965 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1966 messages::internalError(asyncResp->res);
1967 return;
1968 }
1969 });
Gunnar Mills69f35302020-05-17 16:06:31 -05001970}
1971
Ed Tanous8d69c662023-06-21 10:29:06 -07001972inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1973{
1974 if (policy == "AlwaysOn")
1975 {
1976 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1977 }
1978 if (policy == "AlwaysOff")
1979 {
1980 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1981 }
1982 if (policy == "LastState")
1983 {
1984 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1985 }
1986 return "";
1987}
1988
Gunnar Mills69f35302020-05-17 16:06:31 -05001989/**
George Liuc6a620f2020-04-10 17:18:11 +08001990 * @brief Sets power restore policy properties.
1991 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001992 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001993 * @param[in] policy power restore policy properties from request.
1994 *
1995 * @return None.
1996 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001997inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001998 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001999 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08002000{
Ed Tanous62598e32023-07-17 17:06:25 -07002001 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08002002
Ed Tanous8d69c662023-06-21 10:29:06 -07002003 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08002004
Ed Tanous8d69c662023-06-21 10:29:06 -07002005 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08002006 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002007 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06002008 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08002009 return;
2010 }
2011
George Liu9ae226f2023-06-21 17:56:46 +08002012 sdbusplus::asio::setProperty(
2013 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
George Liuc6a620f2020-04-10 17:18:11 +08002014 "/xyz/openbmc_project/control/host0/power_restore_policy",
George Liuc6a620f2020-04-10 17:18:11 +08002015 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
George Liu9ae226f2023-06-21 17:56:46 +08002016 powerRestorePolicy, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002017 if (ec)
2018 {
2019 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2020 messages::internalError(asyncResp->res);
2021 return;
2022 }
2023 });
George Liuc6a620f2020-04-10 17:18:11 +08002024}
2025
AppaRao Pulia6349912019-10-18 17:16:08 +05302026#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
2027/**
2028 * @brief Retrieves provisioning status
2029 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002030 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05302031 *
2032 * @return None.
2033 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002034inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05302035{
Ed Tanous62598e32023-07-17 17:06:25 -07002036 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002037 sdbusplus::asio::getAllProperties(
2038 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
2039 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07002040 [asyncResp](const boost::system::error_code& ec,
2041 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002042 nlohmann::json& oemPFR =
Ed Tanousac106bf2023-06-07 09:24:59 -07002043 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
2044 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
Ed Tanous002d39b2022-05-31 08:59:27 -07002045 "#OemComputerSystem.OpenBmc";
2046 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07002047
Ed Tanous002d39b2022-05-31 08:59:27 -07002048 if (ec)
2049 {
Ed Tanous62598e32023-07-17 17:06:25 -07002050 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002051 // not an error, don't have to have the interface
2052 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2053 return;
2054 }
2055
2056 const bool* provState = nullptr;
2057 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002058
2059 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08002060 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
2061 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002062
2063 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002064 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002065 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002066 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002067 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302068
Ed Tanous002d39b2022-05-31 08:59:27 -07002069 if ((provState == nullptr) || (lockState == nullptr))
2070 {
Ed Tanous62598e32023-07-17 17:06:25 -07002071 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
Ed Tanousac106bf2023-06-07 09:24:59 -07002072 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002073 return;
2074 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302075
Ed Tanous002d39b2022-05-31 08:59:27 -07002076 if (*provState == true)
2077 {
2078 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05302079 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002080 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302081 }
2082 else
2083 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002084 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05302085 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002086 }
2087 else
2088 {
2089 oemPFR["ProvisioningStatus"] = "NotProvisioned";
2090 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002091 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302092}
2093#endif
2094
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302095/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002096 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002097 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002098 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002099 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002100 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002101 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002102inline computer_system::PowerMode
2103 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002104{
Chris Cainb6655102024-02-01 14:35:33 -06002105 using PowerMode = computer_system::PowerMode;
2106
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002107 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002108 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002109 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002110 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002111 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002112 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002113 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002114 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002115 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002116 if (modeString ==
2117 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002118 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002119 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002120 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002121 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002122 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2123 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002124 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002125 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002126 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002127 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2128 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002129 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002130 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002131 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002132 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2133 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002134 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002135 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002136 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002137 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002138 return PowerMode::OEM;
2139 }
2140 // Any other values would be invalid
2141 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2142 return PowerMode::Invalid;
2143}
2144
2145inline void
2146 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2147 const boost::system::error_code& ec,
2148 const dbus::utility::DBusPropertiesMap& properties)
2149{
2150 if (ec)
2151 {
2152 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2153 messages::internalError(asyncResp->res);
2154 return;
2155 }
2156
2157 std::string powerMode;
2158 const std::vector<std::string>* allowedModes = nullptr;
2159 const bool success = sdbusplus::unpackPropertiesNoThrow(
2160 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2161 "AllowedPowerModes", allowedModes);
2162
2163 if (!success)
2164 {
2165 messages::internalError(asyncResp->res);
2166 return;
2167 }
2168
2169 nlohmann::json::array_t modeList;
2170 if (allowedModes == nullptr)
2171 {
2172 modeList.emplace_back("Static");
2173 modeList.emplace_back("MaximumPerformance");
2174 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002175 }
2176 else
2177 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002178 for (const auto& aMode : *allowedModes)
2179 {
2180 computer_system::PowerMode modeValue =
2181 translatePowerModeString(aMode);
2182 if (modeValue == computer_system::PowerMode::Invalid)
2183 {
2184 messages::internalError(asyncResp->res);
2185 continue;
2186 }
2187 modeList.emplace_back(modeValue);
2188 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002189 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002190 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002191
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002192 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2193 const computer_system::PowerMode modeValue =
2194 translatePowerModeString(powerMode);
2195 if (modeValue == computer_system::PowerMode::Invalid)
2196 {
2197 messages::internalError(asyncResp->res);
2198 return;
2199 }
2200 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2201}
Chris Cain3a2d04242021-05-28 16:57:10 -05002202/**
2203 * @brief Retrieves system power mode
2204 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002205 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002206 *
2207 * @return None.
2208 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002209inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002210{
Ed Tanous62598e32023-07-17 17:06:25 -07002211 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002212
2213 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002214 constexpr std::array<std::string_view, 1> interfaces = {
2215 "xyz.openbmc_project.Control.Power.Mode"};
2216 dbus::utility::getSubTree(
2217 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002218 [asyncResp](const boost::system::error_code& ec,
2219 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002220 if (ec)
2221 {
Ed Tanous62598e32023-07-17 17:06:25 -07002222 BMCWEB_LOG_DEBUG("DBUS response error on Power.Mode GetSubTree {}",
2223 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002224 // This is an optional D-Bus object so just return if
2225 // error occurs
2226 return;
2227 }
2228 if (subtree.empty())
2229 {
2230 // As noted above, this is an optional interface so just return
2231 // if there is no instance found
2232 return;
2233 }
2234 if (subtree.size() > 1)
2235 {
2236 // More then one PowerMode object is not supported and is an
2237 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002238 BMCWEB_LOG_DEBUG(
2239 "Found more than 1 system D-Bus Power.Mode objects: {}",
2240 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002241 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002242 return;
2243 }
2244 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2245 {
Ed Tanous62598e32023-07-17 17:06:25 -07002246 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002247 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002248 return;
2249 }
2250 const std::string& path = subtree[0].first;
2251 const std::string& service = subtree[0].second.begin()->first;
2252 if (service.empty())
2253 {
Ed Tanous62598e32023-07-17 17:06:25 -07002254 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002255 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002256 return;
2257 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002258
2259 // Valid Power Mode object found, now read the mode properties
2260 sdbusplus::asio::getAllProperties(
Ed Tanous002d39b2022-05-31 08:59:27 -07002261 *crow::connections::systemBus, service, path,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002262 "xyz.openbmc_project.Control.Power.Mode",
Ed Tanousac106bf2023-06-07 09:24:59 -07002263 [asyncResp](const boost::system::error_code& ec2,
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002264 const dbus::utility::DBusPropertiesMap& properties) {
2265 afterGetPowerMode(asyncResp, ec2, properties);
George Liue99073f2022-12-09 11:06:16 +08002266 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002267 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002268}
2269
2270/**
2271 * @brief Validate the specified mode is valid and return the PowerMode
2272 * name associated with that string
2273 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002274 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002275 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002276 *
2277 * @return PowerMode value or empty string if mode is not valid
2278 */
2279inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002280 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002281 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002282{
Chris Cainb6655102024-02-01 14:35:33 -06002283 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002284 std::string mode;
2285
Chris Cainb6655102024-02-01 14:35:33 -06002286 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002287 {
2288 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2289 }
Chris Cainb6655102024-02-01 14:35:33 -06002290 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002291 {
George Liu0fda0f12021-11-16 10:06:17 +08002292 mode =
2293 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002294 }
Chris Cainb6655102024-02-01 14:35:33 -06002295 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002296 {
2297 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2298 }
Chris Cainb6655102024-02-01 14:35:33 -06002299 else if (modeValue == PowerMode::BalancedPerformance)
2300 {
2301 mode =
2302 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2303 }
2304 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2305 {
2306 mode =
2307 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2308 }
2309 else if (modeValue == PowerMode::EfficiencyFavorPower)
2310 {
2311 mode =
2312 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2313 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002314 else
2315 {
Chris Cainb6655102024-02-01 14:35:33 -06002316 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002317 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002318 }
2319 return mode;
2320}
2321
2322/**
2323 * @brief Sets system power mode.
2324 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002325 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002326 * @param[in] pmode System power mode from request.
2327 *
2328 * @return None.
2329 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002330inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002331 const std::string& pmode)
2332{
Ed Tanous62598e32023-07-17 17:06:25 -07002333 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002334
Ed Tanousac106bf2023-06-07 09:24:59 -07002335 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002336 if (powerMode.empty())
2337 {
2338 return;
2339 }
2340
2341 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002342 constexpr std::array<std::string_view, 1> interfaces = {
2343 "xyz.openbmc_project.Control.Power.Mode"};
2344 dbus::utility::getSubTree(
2345 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002346 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002347 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002348 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002349 if (ec)
2350 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002351 BMCWEB_LOG_ERROR("DBUS response error on Power.Mode GetSubTree {}",
Ed Tanous62598e32023-07-17 17:06:25 -07002352 ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002353 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002354 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002355 return;
2356 }
2357 if (subtree.empty())
2358 {
2359 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002360 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002361 "PowerMode");
2362 return;
2363 }
2364 if (subtree.size() > 1)
2365 {
2366 // More then one PowerMode object is not supported and is an
2367 // error
Ed Tanous62598e32023-07-17 17:06:25 -07002368 BMCWEB_LOG_DEBUG(
2369 "Found more than 1 system D-Bus Power.Mode objects: {}",
2370 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002371 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002372 return;
2373 }
2374 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2375 {
Ed Tanous62598e32023-07-17 17:06:25 -07002376 BMCWEB_LOG_DEBUG("Power.Mode 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 const std::string& path = subtree[0].first;
2381 const std::string& service = subtree[0].second.begin()->first;
2382 if (service.empty())
2383 {
Ed Tanous62598e32023-07-17 17:06:25 -07002384 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002385 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002386 return;
2387 }
2388
Ed Tanous62598e32023-07-17 17:06:25 -07002389 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002390
2391 // Set the Power Mode property
George Liu9ae226f2023-06-21 17:56:46 +08002392 sdbusplus::asio::setProperty(
2393 *crow::connections::systemBus, service, path,
2394 "xyz.openbmc_project.Control.Power.Mode", "PowerMode", powerMode,
Ed Tanousac106bf2023-06-07 09:24:59 -07002395 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002396 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002397 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002398 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002399 messages::internalError(asyncResp->res);
Chris Cain3a2d04242021-05-28 16:57:10 -05002400 return;
2401 }
George Liue99073f2022-12-09 11:06:16 +08002402 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002403 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002404}
2405
2406/**
Yong Li51709ff2019-09-30 14:13:04 +08002407 * @brief Translates watchdog timeout action DBUS property value to redfish.
2408 *
2409 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2410 *
2411 * @return Returns as a string, the timeout action in Redfish terms. If
2412 * translation cannot be done, returns an empty string.
2413 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002414inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002415{
2416 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2417 {
2418 return "None";
2419 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002420 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002421 {
2422 return "ResetSystem";
2423 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002424 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002425 {
2426 return "PowerDown";
2427 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002428 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002429 {
2430 return "PowerCycle";
2431 }
2432
2433 return "";
2434}
2435
2436/**
Yong Lic45f0082019-10-10 14:19:01 +08002437 *@brief Translates timeout action from Redfish to DBUS property value.
2438 *
2439 *@param[in] rfAction The timeout action in Redfish.
2440 *
2441 *@return Returns as a string, the time_out action as expected by DBUS.
2442 *If translation cannot be done, returns an empty string.
2443 */
2444
Ed Tanous23a21a12020-07-25 04:45:05 +00002445inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002446{
2447 if (rfAction == "None")
2448 {
2449 return "xyz.openbmc_project.State.Watchdog.Action.None";
2450 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002451 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002452 {
2453 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2454 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002455 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002456 {
2457 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2458 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002459 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002460 {
2461 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2462 }
2463
2464 return "";
2465}
2466
2467/**
Yong Li51709ff2019-09-30 14:13:04 +08002468 * @brief Retrieves host watchdog timer properties over DBUS
2469 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002470 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002471 *
2472 * @return None.
2473 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002474inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002475 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002476{
Ed Tanous62598e32023-07-17 17:06:25 -07002477 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002478 sdbusplus::asio::getAllProperties(
2479 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2480 "/xyz/openbmc_project/watchdog/host0",
2481 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002482 [asyncResp](const boost::system::error_code& ec,
2483 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002484 if (ec)
2485 {
2486 // watchdog service is stopped
Ed Tanous62598e32023-07-17 17:06:25 -07002487 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002488 return;
2489 }
2490
Ed Tanous62598e32023-07-17 17:06:25 -07002491 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002492
2493 nlohmann::json& hostWatchdogTimer =
Ed Tanousac106bf2023-06-07 09:24:59 -07002494 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002495
2496 // watchdog service is running/enabled
2497 hostWatchdogTimer["Status"]["State"] = "Enabled";
2498
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002499 const bool* enabled = nullptr;
2500 const std::string* expireAction = nullptr;
2501
2502 const bool success = sdbusplus::unpackPropertiesNoThrow(
2503 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2504 "ExpireAction", expireAction);
2505
2506 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002507 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002508 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002509 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002510 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002511
2512 if (enabled != nullptr)
2513 {
2514 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2515 }
2516
2517 if (expireAction != nullptr)
2518 {
2519 std::string action = dbusToRfWatchdogAction(*expireAction);
2520 if (action.empty())
2521 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002522 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002523 return;
2524 }
2525 hostWatchdogTimer["TimeoutAction"] = action;
2526 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002527 });
Yong Li51709ff2019-09-30 14:13:04 +08002528}
2529
2530/**
Yong Lic45f0082019-10-10 14:19:01 +08002531 * @brief Sets Host WatchDog Timer properties.
2532 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002533 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002534 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2535 * RF request.
2536 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2537 *
2538 * @return None.
2539 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002540inline void
2541 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2542 const std::optional<bool> wdtEnable,
2543 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002544{
Ed Tanous62598e32023-07-17 17:06:25 -07002545 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002546
2547 if (wdtTimeOutAction)
2548 {
2549 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2550 // check if TimeOut Action is Valid
2551 if (wdtTimeOutActStr.empty())
2552 {
Ed Tanous62598e32023-07-17 17:06:25 -07002553 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2554 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002555 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002556 "TimeoutAction");
2557 return;
2558 }
2559
George Liu9ae226f2023-06-21 17:56:46 +08002560 sdbusplus::asio::setProperty(
2561 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
Yong Lic45f0082019-10-10 14:19:01 +08002562 "/xyz/openbmc_project/watchdog/host0",
Yong Lic45f0082019-10-10 14:19:01 +08002563 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
George Liu9ae226f2023-06-21 17:56:46 +08002564 wdtTimeOutActStr, [asyncResp](const boost::system::error_code& ec) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002565 if (ec)
2566 {
2567 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
2568 messages::internalError(asyncResp->res);
2569 return;
2570 }
2571 });
Yong Lic45f0082019-10-10 14:19:01 +08002572 }
2573
2574 if (wdtEnable)
2575 {
George Liu9ae226f2023-06-21 17:56:46 +08002576 sdbusplus::asio::setProperty(
2577 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2578 "/xyz/openbmc_project/watchdog/host0",
2579 "xyz.openbmc_project.State.Watchdog", "Enabled", *wdtEnable,
Ed Tanousac106bf2023-06-07 09:24:59 -07002580 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002581 if (ec)
2582 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002583 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002584 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002585 return;
2586 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002587 });
Yong Lic45f0082019-10-10 14:19:01 +08002588 }
2589}
2590
Chris Cain37bbf982021-09-20 10:53:09 -05002591/**
2592 * @brief Parse the Idle Power Saver properties into json
2593 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002594 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002595 * @param[in] properties IPS property data from DBus.
2596 *
2597 * @return true if successful
2598 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002599inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002600 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002601 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002602{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002603 const bool* enabled = nullptr;
2604 const uint8_t* enterUtilizationPercent = nullptr;
2605 const uint64_t* enterDwellTime = nullptr;
2606 const uint8_t* exitUtilizationPercent = nullptr;
2607 const uint64_t* exitDwellTime = nullptr;
2608
2609 const bool success = sdbusplus::unpackPropertiesNoThrow(
2610 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002611 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2612 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2613 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002614
2615 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002616 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002617 return false;
2618 }
2619
2620 if (enabled != nullptr)
2621 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002622 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002623 }
2624
2625 if (enterUtilizationPercent != nullptr)
2626 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002627 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002628 *enterUtilizationPercent;
2629 }
2630
2631 if (enterDwellTime != nullptr)
2632 {
2633 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002634 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002635 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2636 .count();
2637 }
2638
2639 if (exitUtilizationPercent != nullptr)
2640 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002641 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002642 *exitUtilizationPercent;
2643 }
2644
2645 if (exitDwellTime != nullptr)
2646 {
2647 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002648 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002649 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2650 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002651 }
2652
2653 return true;
2654}
2655
2656/**
2657 * @brief Retrieves host watchdog timer properties over DBUS
2658 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002659 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002660 *
2661 * @return None.
2662 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002663inline void
2664 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002665{
Ed Tanous62598e32023-07-17 17:06:25 -07002666 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002667
2668 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002669 constexpr std::array<std::string_view, 1> interfaces = {
2670 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2671 dbus::utility::getSubTree(
2672 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002673 [asyncResp](const boost::system::error_code& ec,
2674 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002675 if (ec)
2676 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002677 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002678 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2679 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002680 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002681 return;
2682 }
2683 if (subtree.empty())
2684 {
2685 // This is an optional interface so just return
2686 // if there is no instance found
Ed Tanous62598e32023-07-17 17:06:25 -07002687 BMCWEB_LOG_DEBUG("No instances found");
Ed Tanous002d39b2022-05-31 08:59:27 -07002688 return;
2689 }
2690 if (subtree.size() > 1)
2691 {
2692 // More then one PowerIdlePowerSaver object is not supported and
2693 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002694 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2695 "Power.IdlePowerSaver objects: {}",
2696 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002697 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002698 return;
2699 }
2700 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2701 {
Ed Tanous62598e32023-07-17 17:06:25 -07002702 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver 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 const std::string& path = subtree[0].first;
2707 const std::string& service = subtree[0].second.begin()->first;
2708 if (service.empty())
2709 {
Ed Tanous62598e32023-07-17 17:06:25 -07002710 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002711 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002712 return;
2713 }
2714
2715 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002716 sdbusplus::asio::getAllProperties(
2717 *crow::connections::systemBus, service, path,
2718 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanousac106bf2023-06-07 09:24:59 -07002719 [asyncResp](const boost::system::error_code& ec2,
2720 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002721 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002722 {
Ed Tanous62598e32023-07-17 17:06:25 -07002723 BMCWEB_LOG_ERROR(
2724 "DBUS response error on IdlePowerSaver GetAll: {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002725 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002726 return;
2727 }
2728
Ed Tanousac106bf2023-06-07 09:24:59 -07002729 if (!parseIpsProperties(asyncResp, properties))
Ed Tanous002d39b2022-05-31 08:59:27 -07002730 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002731 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002732 return;
2733 }
George Liue99073f2022-12-09 11:06:16 +08002734 });
Patrick Williams5a39f772023-10-20 11:20:21 -05002735 });
Chris Cain37bbf982021-09-20 10:53:09 -05002736
Ed Tanous62598e32023-07-17 17:06:25 -07002737 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002738}
2739
2740/**
2741 * @brief Sets Idle Power Saver properties.
2742 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002743 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002744 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2745 * RF request.
2746 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2747 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2748 * before entering idle state.
2749 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2750 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2751 * before exiting idle state
2752 *
2753 * @return None.
2754 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002755inline void
2756 setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2757 const std::optional<bool> ipsEnable,
2758 const std::optional<uint8_t> ipsEnterUtil,
2759 const std::optional<uint64_t> ipsEnterTime,
2760 const std::optional<uint8_t> ipsExitUtil,
2761 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002762{
Ed Tanous62598e32023-07-17 17:06:25 -07002763 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002764
2765 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002766 constexpr std::array<std::string_view, 1> interfaces = {
2767 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2768 dbus::utility::getSubTree(
2769 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002770 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002771 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002772 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002773 if (ec)
2774 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002775 BMCWEB_LOG_ERROR(
Ed Tanous62598e32023-07-17 17:06:25 -07002776 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2777 ec);
Ed Tanousac106bf2023-06-07 09:24:59 -07002778 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002779 return;
2780 }
2781 if (subtree.empty())
2782 {
2783 // This is an optional D-Bus object, but user attempted to patch
Ed Tanousac106bf2023-06-07 09:24:59 -07002784 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
Ed Tanous002d39b2022-05-31 08:59:27 -07002785 "IdlePowerSaver");
2786 return;
2787 }
2788 if (subtree.size() > 1)
2789 {
2790 // More then one PowerIdlePowerSaver object is not supported and
2791 // is an error
Ed Tanous62598e32023-07-17 17:06:25 -07002792 BMCWEB_LOG_DEBUG(
2793 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2794 subtree.size());
Ed Tanousac106bf2023-06-07 09:24:59 -07002795 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002796 return;
2797 }
2798 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2799 {
Ed Tanous62598e32023-07-17 17:06:25 -07002800 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002801 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002802 return;
2803 }
2804 const std::string& path = subtree[0].first;
2805 const std::string& service = subtree[0].second.begin()->first;
2806 if (service.empty())
2807 {
Ed Tanous62598e32023-07-17 17:06:25 -07002808 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002809 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002810 return;
2811 }
Chris Cain37bbf982021-09-20 10:53:09 -05002812
Ed Tanous002d39b2022-05-31 08:59:27 -07002813 // Valid Power IdlePowerSaver object found, now set any values that
2814 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002815
Ed Tanous002d39b2022-05-31 08:59:27 -07002816 if (ipsEnable)
2817 {
George Liu9ae226f2023-06-21 17:56:46 +08002818 sdbusplus::asio::setProperty(
2819 *crow::connections::systemBus, service, path,
Ed Tanous002d39b2022-05-31 08:59:27 -07002820 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
George Liu9ae226f2023-06-21 17:56:46 +08002821 *ipsEnable, [asyncResp](const boost::system::error_code& ec2) {
Patrick Williams5a39f772023-10-20 11:20:21 -05002822 if (ec2)
2823 {
2824 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
2825 messages::internalError(asyncResp->res);
2826 return;
2827 }
2828 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002829 }
2830 if (ipsEnterUtil)
2831 {
George Liu9ae226f2023-06-21 17:56:46 +08002832 sdbusplus::asio::setProperty(
2833 *crow::connections::systemBus, service, path,
2834 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2835 "EnterUtilizationPercent", *ipsEnterUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002836 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002837 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002838 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002839 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002840 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002841 return;
2842 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002843 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002844 }
2845 if (ipsEnterTime)
2846 {
2847 // Convert from seconds into milliseconds for DBus
2848 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002849 sdbusplus::asio::setProperty(
2850 *crow::connections::systemBus, service, path,
2851 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2852 "EnterDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002853 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002854 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002855 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002856 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002857 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002858 return;
2859 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002860 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002861 }
2862 if (ipsExitUtil)
2863 {
George Liu9ae226f2023-06-21 17:56:46 +08002864 sdbusplus::asio::setProperty(
2865 *crow::connections::systemBus, service, path,
2866 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2867 "ExitUtilizationPercent", *ipsExitUtil,
Ed Tanousac106bf2023-06-07 09:24:59 -07002868 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002869 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002870 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002871 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002872 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002873 return;
2874 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002875 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002876 }
2877 if (ipsExitTime)
2878 {
2879 // Convert from seconds into milliseconds for DBus
2880 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
George Liu9ae226f2023-06-21 17:56:46 +08002881 sdbusplus::asio::setProperty(
2882 *crow::connections::systemBus, service, path,
2883 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2884 "ExitDwellTime", timeMilliseconds,
Ed Tanousac106bf2023-06-07 09:24:59 -07002885 [asyncResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002886 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002887 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002888 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
Ed Tanousac106bf2023-06-07 09:24:59 -07002889 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -07002890 return;
2891 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002892 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002893 }
Patrick Williams5a39f772023-10-20 11:20:21 -05002894 });
Chris Cain37bbf982021-09-20 10:53:09 -05002895
Ed Tanous62598e32023-07-17 17:06:25 -07002896 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002897}
2898
Ed Tanousc1e219d2023-06-07 10:34:33 -07002899inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002900 crow::App& app, const crow::Request& req,
2901 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2902{
2903 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2904 {
2905 return;
2906 }
2907 asyncResp->res.addHeader(
2908 boost::beast::http::field::link,
2909 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2910}
2911
Ed Tanousc1e219d2023-06-07 10:34:33 -07002912inline void handleComputerSystemCollectionGet(
2913 crow::App& app, const crow::Request& req,
2914 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2915{
2916 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2917 {
2918 return;
2919 }
2920
2921 asyncResp->res.addHeader(
2922 boost::beast::http::field::link,
2923 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2924 asyncResp->res.jsonValue["@odata.type"] =
2925 "#ComputerSystemCollection.ComputerSystemCollection";
2926 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2927 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2928
2929 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2930 ifaceArray = nlohmann::json::array();
2931 if constexpr (bmcwebEnableMultiHost)
2932 {
2933 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2934 // Option currently returns no systems. TBD
2935 return;
2936 }
2937 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2938 nlohmann::json::object_t system;
2939 system["@odata.id"] = "/redfish/v1/Systems/system";
2940 ifaceArray.emplace_back(std::move(system));
2941 sdbusplus::asio::getProperty<std::string>(
2942 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2943 "/xyz/openbmc_project/network/hypervisor",
2944 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
2945 [asyncResp](const boost::system::error_code& ec2,
2946 const std::string& /*hostName*/) {
2947 if (ec2)
2948 {
2949 return;
2950 }
2951 auto val = asyncResp->res.jsonValue.find("Members@odata.count");
2952 if (val == asyncResp->res.jsonValue.end())
2953 {
Ed Tanous62598e32023-07-17 17:06:25 -07002954 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002955 return;
2956 }
2957 uint64_t* count = val->get_ptr<uint64_t*>();
2958 if (count == nullptr)
2959 {
Ed Tanous62598e32023-07-17 17:06:25 -07002960 BMCWEB_LOG_CRITICAL("Count wasn't found??");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002961 return;
2962 }
2963 *count = *count + 1;
Ed Tanous62598e32023-07-17 17:06:25 -07002964 BMCWEB_LOG_DEBUG("Hypervisor is available");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002965 nlohmann::json& ifaceArray2 = asyncResp->res.jsonValue["Members"];
2966 nlohmann::json::object_t hypervisor;
2967 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2968 ifaceArray2.emplace_back(std::move(hypervisor));
Patrick Williams5a39f772023-10-20 11:20:21 -05002969 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07002970}
2971
Yong Lic45f0082019-10-10 14:19:01 +08002972/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002973 * Function transceives data with dbus directly.
2974 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002975inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002976{
Patrick Williams89492a12023-05-10 07:51:34 -05002977 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2978 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2979 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002980 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002981 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002982
2983 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002984 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002985 if (ec)
2986 {
Ed Tanous62598e32023-07-17 17:06:25 -07002987 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -07002988 messages::internalError(asyncResp->res);
2989 return;
2990 }
2991 messages::success(asyncResp->res);
Patrick Williams5a39f772023-10-20 11:20:21 -05002992 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002993 serviceName, objectPath, interfaceName, method);
2994}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002995
Ed Tanousc1e219d2023-06-07 10:34:33 -07002996inline void handleComputerSystemResetActionPost(
2997 crow::App& app, const crow::Request& req,
2998 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2999 const std::string& systemName)
3000{
3001 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3002 {
3003 return;
3004 }
3005 if (systemName != "system")
3006 {
3007 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3008 systemName);
3009 return;
3010 }
3011 if constexpr (bmcwebEnableMultiHost)
3012 {
3013 // Option currently returns no systems. TBD
3014 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3015 systemName);
3016 return;
3017 }
3018 std::string resetType;
3019 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
3020 {
3021 return;
3022 }
3023
3024 // Get the command and host vs. chassis
3025 std::string command;
3026 bool hostCommand = true;
3027 if ((resetType == "On") || (resetType == "ForceOn"))
3028 {
3029 command = "xyz.openbmc_project.State.Host.Transition.On";
3030 hostCommand = true;
3031 }
3032 else if (resetType == "ForceOff")
3033 {
3034 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
3035 hostCommand = false;
3036 }
3037 else if (resetType == "ForceRestart")
3038 {
3039 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
3040 hostCommand = true;
3041 }
3042 else if (resetType == "GracefulShutdown")
3043 {
3044 command = "xyz.openbmc_project.State.Host.Transition.Off";
3045 hostCommand = true;
3046 }
3047 else if (resetType == "GracefulRestart")
3048 {
3049 command =
3050 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
3051 hostCommand = true;
3052 }
3053 else if (resetType == "PowerCycle")
3054 {
3055 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
3056 hostCommand = true;
3057 }
3058 else if (resetType == "Nmi")
3059 {
3060 doNMI(asyncResp);
3061 return;
3062 }
3063 else
3064 {
3065 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
3066 return;
3067 }
Ed Tanousd02aad32024-02-13 14:43:34 -08003068 sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
Ed Tanousc1e219d2023-06-07 10:34:33 -07003069
3070 if (hostCommand)
3071 {
Ed Tanousd02aad32024-02-13 14:43:34 -08003072 setDbusProperty(asyncResp, "xyz.openbmc_project.State.Host",
3073 statePath / "host0", "xyz.openbmc_project.State.Host",
3074 "RequestedHostTransition", "Reset", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003075 }
3076 else
3077 {
Ed Tanousd02aad32024-02-13 14:43:34 -08003078 setDbusProperty(asyncResp, "xyz.openbmc_project.State.Chassis",
3079 statePath / "chassis0",
3080 "xyz.openbmc_project.State.Chassis",
3081 "RequestedPowerTransition", "Reset", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003082 }
3083}
3084
Ed Tanousc1e219d2023-06-07 10:34:33 -07003085inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003086 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003087 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3088 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003089{
3090 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3091 {
3092 return;
3093 }
3094
3095 asyncResp->res.addHeader(
3096 boost::beast::http::field::link,
3097 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3098}
3099
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003100inline void afterPortRequest(
3101 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3102 const boost::system::error_code& ec,
3103 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
3104{
3105 if (ec)
3106 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003107 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003108 messages::internalError(asyncResp->res);
3109 return;
3110 }
3111 for (const auto& data : socketData)
3112 {
3113 const std::string& socketPath = get<0>(data);
3114 const std::string& protocolName = get<1>(data);
3115 bool isProtocolEnabled = get<2>(data);
3116 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
3117 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
3118 // need to retrieve port number for
3119 // obmc-console-ssh service
3120 if (protocolName == "SSH")
3121 {
3122 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003123 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003124 int portNumber) {
3125 if (ec1)
3126 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003127 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003128 messages::internalError(asyncResp->res);
3129 return;
3130 }
3131 nlohmann::json& dataJson1 =
3132 asyncResp->res.jsonValue["SerialConsole"];
3133 dataJson1[protocolName]["Port"] = portNumber;
3134 });
3135 }
3136 }
3137}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003138
3139inline void
3140 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3141 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3142 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003143{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003144 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3145 {
3146 return;
3147 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003148
Ed Tanousc1e219d2023-06-07 10:34:33 -07003149 if constexpr (bmcwebEnableMultiHost)
3150 {
3151 // Option currently returns no systems. TBD
3152 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3153 systemName);
3154 return;
3155 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003156
Ed Tanousc1e219d2023-06-07 10:34:33 -07003157 if (systemName == "hypervisor")
3158 {
3159 handleHypervisorSystemGet(asyncResp);
3160 return;
3161 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003162
Ed Tanousc1e219d2023-06-07 10:34:33 -07003163 if (systemName != "system")
3164 {
3165 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3166 systemName);
3167 return;
3168 }
3169 asyncResp->res.addHeader(
3170 boost::beast::http::field::link,
3171 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3172 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003173 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanousc1e219d2023-06-07 10:34:33 -07003174 asyncResp->res.jsonValue["Name"] = "system";
3175 asyncResp->res.jsonValue["Id"] = "system";
3176 asyncResp->res.jsonValue["SystemType"] = "Physical";
3177 asyncResp->res.jsonValue["Description"] = "Computer System";
3178 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003179 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003180 double(0);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003181 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07003182
Ed Tanousc1e219d2023-06-07 10:34:33 -07003183 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
3184 "/redfish/v1/Systems/system/Processors";
3185 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
3186 "/redfish/v1/Systems/system/Memory";
3187 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
3188 "/redfish/v1/Systems/system/Storage";
3189 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
3190 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08003191
Ed Tanousc1e219d2023-06-07 10:34:33 -07003192 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
3193 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
3194 asyncResp->res
3195 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
3196 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003197
Ed Tanousc1e219d2023-06-07 10:34:33 -07003198 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
3199 "/redfish/v1/Systems/system/LogServices";
3200 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
3201 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003202
Ed Tanousc1e219d2023-06-07 10:34:33 -07003203 nlohmann::json::array_t managedBy;
3204 nlohmann::json& manager = managedBy.emplace_back();
3205 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3206 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3207 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3208 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003209
Ed Tanousc1e219d2023-06-07 10:34:33 -07003210 // Fill in SerialConsole info
3211 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3212 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003213
Ed Tanousc1e219d2023-06-07 10:34:33 -07003214 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3215 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3216 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3217 "Press ~. to exit console";
3218 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3219 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003220
3221#ifdef BMCWEB_ENABLE_KVM
Ed Tanousc1e219d2023-06-07 10:34:33 -07003222 // Fill in GraphicalConsole info
3223 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3224 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] = 4;
3225 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3226 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003227
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003228#endif // BMCWEB_ENABLE_KVM
James Feistb49ac872019-05-21 15:12:01 -07003229
Ed Tanousc1e219d2023-06-07 10:34:33 -07003230 auto health = std::make_shared<HealthPopulate>(asyncResp);
3231 if constexpr (bmcwebEnableHealthPopulate)
3232 {
3233 constexpr std::array<std::string_view, 4> inventoryForSystems{
3234 "xyz.openbmc_project.Inventory.Item.Dimm",
3235 "xyz.openbmc_project.Inventory.Item.Cpu",
3236 "xyz.openbmc_project.Inventory.Item.Drive",
3237 "xyz.openbmc_project.Inventory.Item.StorageController"};
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003238
Ed Tanousc1e219d2023-06-07 10:34:33 -07003239 dbus::utility::getSubTreePaths(
3240 "/", 0, inventoryForSystems,
3241 [health](const boost::system::error_code& ec,
3242 const std::vector<std::string>& resp) {
3243 if (ec)
3244 {
3245 // no inventory
3246 return;
3247 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003248
Ed Tanousc1e219d2023-06-07 10:34:33 -07003249 health->inventory = resp;
Patrick Williams5a39f772023-10-20 11:20:21 -05003250 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003251 health->populate();
3252 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003253
Ed Tanousc1e219d2023-06-07 10:34:33 -07003254 getMainChassisId(asyncResp,
3255 [](const std::string& chassisId,
3256 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3257 nlohmann::json::array_t chassisArray;
3258 nlohmann::json& chassis = chassisArray.emplace_back();
3259 chassis["@odata.id"] = boost::urls::format("/redfish/v1/Chassis/{}",
3260 chassisId);
3261 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3262 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003263
George Liu59a17e42022-10-08 09:27:47 +08003264 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003265 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3266 getIndicatorLedState(asyncResp);
Gunnar Mills51bd2d82024-04-01 15:25:51 -05003267 getComputerSystem(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003268 getHostState(asyncResp);
3269 getBootProperties(asyncResp);
3270 getBootProgress(asyncResp);
3271 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003272 pcie_util::getPCIeDeviceList(asyncResp,
3273 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003274 getHostWatchdogTimer(asyncResp);
3275 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003276 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003277 getAutomaticRetryPolicy(asyncResp);
3278 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003279#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanousc1e219d2023-06-07 10:34:33 -07003280 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003281#endif
Ed Tanousc1e219d2023-06-07 10:34:33 -07003282 getTrustedModuleRequiredToBoot(asyncResp);
3283 getPowerMode(asyncResp);
3284 getIdlePowerSaver(asyncResp);
3285}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003286
Ed Tanousc1e219d2023-06-07 10:34:33 -07003287inline void handleComputerSystemPatch(
3288 crow::App& app, const crow::Request& req,
3289 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3290 const std::string& systemName)
3291{
3292 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3293 {
3294 return;
3295 }
3296 if constexpr (bmcwebEnableMultiHost)
3297 {
3298 // Option currently returns no systems. TBD
3299 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3300 systemName);
3301 return;
3302 }
3303 if (systemName != "system")
3304 {
3305 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3306 systemName);
3307 return;
3308 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003309
Ed Tanousc1e219d2023-06-07 10:34:33 -07003310 asyncResp->res.addHeader(
3311 boost::beast::http::field::link,
3312 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003313
Ed Tanousc1e219d2023-06-07 10:34:33 -07003314 std::optional<bool> locationIndicatorActive;
3315 std::optional<std::string> indicatorLed;
3316 std::optional<std::string> assetTag;
3317 std::optional<std::string> powerRestorePolicy;
3318 std::optional<std::string> powerMode;
3319 std::optional<bool> wdtEnable;
3320 std::optional<std::string> wdtTimeOutAction;
3321 std::optional<std::string> bootSource;
3322 std::optional<std::string> bootType;
3323 std::optional<std::string> bootEnable;
3324 std::optional<std::string> bootAutomaticRetry;
3325 std::optional<uint32_t> bootAutomaticRetryAttempts;
3326 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003327 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003328 std::optional<bool> ipsEnable;
3329 std::optional<uint8_t> ipsEnterUtil;
3330 std::optional<uint64_t> ipsEnterTime;
3331 std::optional<uint8_t> ipsExitUtil;
3332 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003333
Ed Tanousc1e219d2023-06-07 10:34:33 -07003334 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003335 if (!json_util::readJsonPatch(
3336 req, asyncResp->res,
3337 "IndicatorLED", indicatorLed,
3338 "LocationIndicatorActive", locationIndicatorActive,
3339 "AssetTag", assetTag,
3340 "PowerRestorePolicy", powerRestorePolicy,
3341 "PowerMode", powerMode,
3342 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3343 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3344 "Boot/BootSourceOverrideTarget", bootSource,
3345 "Boot/BootSourceOverrideMode", bootType,
3346 "Boot/BootSourceOverrideEnabled", bootEnable,
3347 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
Corey Hardesty797d5da2022-04-26 17:54:52 +08003348 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
Ed Tanous22d268c2022-05-19 09:39:07 -07003349 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003350 "Boot/StopBootOnFault", stopBootOnFault,
Ed Tanous22d268c2022-05-19 09:39:07 -07003351 "IdlePowerSaver/Enabled", ipsEnable,
3352 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3353 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3354 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3355 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3356 {
3357 return;
3358 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003359 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003360
Ed Tanousc1e219d2023-06-07 10:34:33 -07003361 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003362
Ed Tanousc1e219d2023-06-07 10:34:33 -07003363 if (assetTag)
3364 {
3365 setAssetTag(asyncResp, *assetTag);
3366 }
James Feistb49ac872019-05-21 15:12:01 -07003367
Ed Tanousc1e219d2023-06-07 10:34:33 -07003368 if (wdtEnable || wdtTimeOutAction)
3369 {
3370 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3371 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003372
Ed Tanousc1e219d2023-06-07 10:34:33 -07003373 if (bootSource || bootType || bootEnable)
3374 {
3375 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3376 }
3377 if (bootAutomaticRetry)
3378 {
3379 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3380 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003381
Ed Tanousc1e219d2023-06-07 10:34:33 -07003382 if (bootAutomaticRetryAttempts)
3383 {
3384 setAutomaticRetryAttempts(asyncResp,
3385 bootAutomaticRetryAttempts.value());
3386 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003387
Ed Tanousc1e219d2023-06-07 10:34:33 -07003388 if (bootTrustedModuleRequired)
3389 {
3390 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3391 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003392
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003393 if (stopBootOnFault)
3394 {
3395 setStopBootOnFault(asyncResp, *stopBootOnFault);
3396 }
3397
Ed Tanousc1e219d2023-06-07 10:34:33 -07003398 if (locationIndicatorActive)
3399 {
George Liu59a17e42022-10-08 09:27:47 +08003400 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003401 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003402
Ed Tanousc1e219d2023-06-07 10:34:33 -07003403 // TODO (Gunnar): Remove IndicatorLED after enough time has
3404 // passed
3405 if (indicatorLed)
3406 {
3407 setIndicatorLedState(asyncResp, *indicatorLed);
3408 asyncResp->res.addHeader(boost::beast::http::field::warning,
3409 "299 - \"IndicatorLED is deprecated. Use "
3410 "LocationIndicatorActive instead.\"");
3411 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003412
Ed Tanousc1e219d2023-06-07 10:34:33 -07003413 if (powerRestorePolicy)
3414 {
3415 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3416 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003417
Ed Tanousc1e219d2023-06-07 10:34:33 -07003418 if (powerMode)
3419 {
3420 setPowerMode(asyncResp, *powerMode);
3421 }
Chris Cain37bbf982021-09-20 10:53:09 -05003422
Ed Tanousc1e219d2023-06-07 10:34:33 -07003423 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3424 {
3425 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3426 ipsExitUtil, ipsExitTime);
3427 }
3428}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303429
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003430inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003431 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003432 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003433 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003434{
3435 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3436 {
3437 return;
3438 }
3439 asyncResp->res.addHeader(
3440 boost::beast::http::field::link,
3441 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3442}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003443
3444/**
3445 * @brief Translates allowed host transitions to redfish string
3446 *
3447 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3448 * @param[out] allowableValues The translated host transition(s)
3449 *
3450 * @return Emplaces correpsonding Redfish translated value(s) in
3451 * allowableValues. If translation not possible, does nothing to
3452 * allowableValues.
3453 */
3454inline void
3455 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3456 nlohmann::json::array_t& allowableValues)
3457{
3458 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3459 {
3460 allowableValues.emplace_back(resource::ResetType::On);
3461 allowableValues.emplace_back(resource::ResetType::ForceOn);
3462 }
3463 else if (dbusAllowedHostTran ==
3464 "xyz.openbmc_project.State.Host.Transition.Off")
3465 {
3466 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3467 }
3468 else if (dbusAllowedHostTran ==
3469 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3470 {
3471 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3472 }
3473 else if (dbusAllowedHostTran ==
3474 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3475 {
3476 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3477 }
3478 else
3479 {
3480 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3481 }
3482}
3483
3484inline void afterGetAllowedHostTransitions(
3485 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3486 const boost::system::error_code& ec,
3487 const std::vector<std::string>& allowedHostTransitions)
3488{
3489 nlohmann::json::array_t allowableValues;
3490
3491 // Supported on all systems currently
3492 allowableValues.emplace_back(resource::ResetType::ForceOff);
3493 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3494 allowableValues.emplace_back(resource::ResetType::Nmi);
3495
3496 if (ec)
3497 {
Ed Tanouse715d142024-03-07 15:47:37 -08003498 if ((ec.value() ==
3499 boost::system::linux_error::bad_request_descriptor) ||
3500 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003501 {
3502 // Property not implemented so just return defaults
3503 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3504 allowableValues.emplace_back(resource::ResetType::On);
3505 allowableValues.emplace_back(resource::ResetType::ForceOn);
3506 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3507 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3508 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3509 }
3510 else
3511 {
3512 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3513 messages::internalError(asyncResp->res);
3514 return;
3515 }
3516 }
3517 else
3518 {
3519 for (const std::string& transition : allowedHostTransitions)
3520 {
3521 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3522 dbusToRfAllowedHostTransitions(transition, allowableValues);
3523 }
3524 }
3525
3526 nlohmann::json::object_t parameter;
3527 parameter["Name"] = "ResetType";
3528 parameter["Required"] = true;
3529 parameter["DataType"] = "String";
3530 parameter["AllowableValues"] = std::move(allowableValues);
3531 nlohmann::json::array_t parameters;
3532 parameters.emplace_back(std::move(parameter));
3533 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3534}
3535
Ed Tanousc1e219d2023-06-07 10:34:33 -07003536inline void handleSystemCollectionResetActionGet(
3537 crow::App& app, const crow::Request& req,
3538 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3539 const std::string& systemName)
3540{
3541 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3542 {
3543 return;
3544 }
3545 if constexpr (bmcwebEnableMultiHost)
3546 {
3547 // Option currently returns no systems. TBD
3548 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3549 systemName);
3550 return;
3551 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003552
Ed Tanousc1e219d2023-06-07 10:34:33 -07003553 if (systemName == "hypervisor")
3554 {
3555 handleHypervisorResetActionGet(asyncResp);
3556 return;
3557 }
3558
3559 if (systemName != "system")
3560 {
3561 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3562 systemName);
3563 return;
3564 }
3565
3566 asyncResp->res.addHeader(
3567 boost::beast::http::field::link,
3568 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3569
3570 asyncResp->res.jsonValue["@odata.id"] =
3571 "/redfish/v1/Systems/system/ResetActionInfo";
3572 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3573 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3574 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3575
Andrew Geissler33e1f122024-02-26 21:10:16 -06003576 // Look to see if system defines AllowedHostTransitions
3577 sdbusplus::asio::getProperty<std::vector<std::string>>(
3578 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3579 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
3580 "AllowedHostTransitions",
3581 [asyncResp](const boost::system::error_code& ec,
3582 const std::vector<std::string>& allowedHostTransitions) {
3583 afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
3584 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003585}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303586/**
3587 * SystemResetActionInfo derived class for delivering Computer Systems
3588 * ResetType AllowableValues using ResetInfo schema.
3589 */
Ed Tanous100afe52023-06-07 13:30:46 -07003590inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303591{
Ed Tanous100afe52023-06-07 13:30:46 -07003592 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3593 .privileges(redfish::privileges::headComputerSystemCollection)
3594 .methods(boost::beast::http::verb::head)(
3595 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3596
3597 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3598 .privileges(redfish::privileges::getComputerSystemCollection)
3599 .methods(boost::beast::http::verb::get)(
3600 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3601
3602 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3603 .privileges(redfish::privileges::headComputerSystem)
3604 .methods(boost::beast::http::verb::head)(
3605 std::bind_front(handleComputerSystemHead, std::ref(app)));
3606
3607 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3608 .privileges(redfish::privileges::getComputerSystem)
3609 .methods(boost::beast::http::verb::get)(
3610 std::bind_front(handleComputerSystemGet, std::ref(app)));
3611
3612 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3613 .privileges(redfish::privileges::patchComputerSystem)
3614 .methods(boost::beast::http::verb::patch)(
3615 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3616
3617 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3618 .privileges(redfish::privileges::postComputerSystem)
3619 .methods(boost::beast::http::verb::post)(std::bind_front(
3620 handleComputerSystemResetActionPost, std::ref(app)));
3621
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003622 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003623 .privileges(redfish::privileges::headActionInfo)
3624 .methods(boost::beast::http::verb::head)(std::bind_front(
3625 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003626 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003627 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003628 .methods(boost::beast::http::verb::get)(std::bind_front(
3629 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003630}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003631} // namespace redfish