blob: b86461f4a330f798cd69ddfb0b7c3a0aa4ded2aa [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02004#pragma once
5
Willy Tu13451e32023-05-24 16:08:18 -07006#include "bmcweb_config.h"
7
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08008#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07009#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080010#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070011#include "generated/enums/action_info.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070012#include "generated/enums/computer_system.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070013#include "generated/enums/open_bmc_computer_system.hpp"
Andrew Geissler33e1f122024-02-26 21:10:16 -060014#include "generated/enums/resource.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060015#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080016#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070017#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080018#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080019#include "registries/privilege_registry.hpp"
20#include "utils/dbus_utils.hpp"
21#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050022#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080023#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070024#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080025
Andrew Geisslerfc903b32023-05-31 14:15:42 -040026#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070027#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080028#include <boost/system/error_code.hpp>
Andrew Geissler33e1f122024-02-26 21:10:16 -060029#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070030#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070031#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040032#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020033#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050034
George Liu7a1dbc42022-12-07 16:03:22 +080035#include <array>
Andrew Geissler33e1f122024-02-26 21:10:16 -060036#include <memory>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060037#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080038#include <string_view>
Ed Tanous20fa6a22024-05-20 18:02:58 -070039#include <utility>
Ed Tanousabf2add2019-01-22 16:40:12 -080040#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060041#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020042
Ed Tanous1abe55e2018-09-05 08:30:59 -070043namespace redfish
44{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020045
Abhishek Patel5c3e9272021-06-24 10:11:33 -050046const static std::array<std::pair<std::string_view, std::string_view>, 2>
47 protocolToDBusForSystems{
48 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
49
Alpana Kumari9d3ae102019-04-12 06:49:32 -050050/**
51 * @brief Updates the Functional State of DIMMs
52 *
Ed Tanousac106bf2023-06-07 09:24:59 -070053 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050054 * @param[in] dimmState Dimm's Functional state, true/false
55 *
56 * @return None.
57 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -040058inline void updateDimmProperties(
59 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050060{
Ed Tanous62598e32023-07-17 17:06:25 -070061 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050062
Gunnar Mills4e0453b2020-07-08 14:00:30 -050063 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050064 // Update STATE only if previous State was DISABLED and current Dimm is
65 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070066 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070067 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050068 if (prevMemSummary == "Disabled")
69 {
Ed Tanouse05aec52022-01-25 10:28:56 -080070 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050071 {
Ed Tanousac106bf2023-06-07 09:24:59 -070072 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050073 "Enabled";
74 }
75 }
76}
77
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050078/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079 * @brief Update "ProcessorSummary" "Status" "State" based on
80 * CPU Functional State
81 *
Ed Tanousac106bf2023-06-07 09:24:59 -070082 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050083 * @param[in] cpuFunctionalState is CPU functional true/false
84 *
85 * @return None.
86 */
Ed Tanousac106bf2023-06-07 09:24:59 -070087inline void modifyCpuFunctionalState(
88 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089{
Ed Tanous62598e32023-07-17 17:06:25 -070090 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050091
Ed Tanous02cad962022-06-30 16:50:15 -070092 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -070093 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050094
Gunnar Mills4e0453b2020-07-08 14:00:30 -050095 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050096 // Update STATE only if previous State was Non_Functional and current CPU is
97 // Functional.
98 if (prevProcState == "Disabled")
99 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800100 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700102 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500103 "Enabled";
104 }
105 }
106}
107
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500108/*
109 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
110 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700111 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500112 * @param[in] cpuPresenceState CPU present or not
113 *
114 * @return None.
115 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400116inline void modifyCpuPresenceState(
117 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500118{
Ed Tanous62598e32023-07-17 17:06:25 -0700119 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500120
121 if (isCpuPresent)
122 {
123 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700124 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500125 auto* procCountPtr =
126 procCount.get_ptr<nlohmann::json::number_integer_t*>();
127 if (procCountPtr != nullptr)
128 {
129 // shouldn't be possible to be nullptr
130 *procCountPtr += 1;
131 }
132 }
133}
134
Ali Ahmed382d6472021-09-03 16:53:53 -0500135inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700136 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500137 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
138 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500139{
Ed Tanous62598e32023-07-17 17:06:25 -0700140 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500141
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200142 // TODO: Get Model
143
144 const uint16_t* coreCount = nullptr;
145
146 const bool success = sdbusplus::unpackPropertiesNoThrow(
147 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
148
149 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500150 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700151 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200152 return;
153 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500154
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200155 if (coreCount != nullptr)
156 {
157 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700158 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200159 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500160
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200161 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500162 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200163 coreCountJson = *coreCount;
164 }
165 else
166 {
167 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500168 }
169 }
170}
171
172/*
173 * @brief Get ProcessorSummary fields
174 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700175 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500176 * @param[in] service dbus service for Cpu Information
177 * @param[in] path dbus path for Cpu
178 *
179 * @return None.
180 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700181inline void
182 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
183 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500184{
Ed Tanousac106bf2023-06-07 09:24:59 -0700185 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
186 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500187 if (ec3)
188 {
Ed Tanous62598e32023-07-17 17:06:25 -0700189 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500190 return;
191 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700192 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500193 };
194
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500195 // Get the Presence of CPU
Ed Tanousdeae6a72024-11-11 21:58:57 -0800196 dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
197 path, "xyz.openbmc_project.Inventory.Item",
198 "Present", std::move(getCpuPresenceState));
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500199
Ed Tanousdeae6a72024-11-11 21:58:57 -0800200 dbus::utility::getAllProperties(
201 service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700202 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800203 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800204 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400205 if (ec2)
206 {
207 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
208 messages::internalError(asyncResp->res);
209 return;
210 }
211 getProcessorProperties(asyncResp, properties);
212 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500213}
214
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500215/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500216 * @brief processMemoryProperties fields
217 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700218 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500219 * @param[in] DBUS properties for memory
220 *
221 * @return None.
222 */
223inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700224 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500225 const dbus::utility::DBusPropertiesMap& properties)
226{
Ed Tanous62598e32023-07-17 17:06:25 -0700227 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500228
229 if (properties.empty())
230 {
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500231 return;
232 }
233
234 const size_t* memorySizeInKB = nullptr;
235
236 const bool success = sdbusplus::unpackPropertiesNoThrow(
237 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
238 memorySizeInKB);
239
240 if (!success)
241 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700242 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500243 return;
244 }
245
246 if (memorySizeInKB != nullptr)
247 {
248 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700249 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500250 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500251 if (preValue == nullptr)
252 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700253 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500254 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500255 }
256 else
257 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700258 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500259 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
260 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500261 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500262 }
263}
264
265/*
266 * @brief Get getMemorySummary fields
267 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700268 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500269 * @param[in] service dbus service for memory Information
270 * @param[in] path dbus path for memory
271 *
272 * @return None.
273 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700274inline void
275 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
276 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500277{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800278 dbus::utility::getAllProperties(
279 service, path, "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700280 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500281 path](const boost::system::error_code& ec2,
282 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400283 if (ec2)
284 {
285 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
286 messages::internalError(asyncResp->res);
287 return;
288 }
289 processMemoryProperties(asyncResp, properties);
290 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500291}
292
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500293inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
294 const boost::system::error_code& ec,
295 const dbus::utility::DBusPropertiesMap& properties)
296{
297 if (ec)
298 {
299 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
300 messages::internalError(asyncResp->res);
301 return;
302 }
303 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
304
305 const std::string* uUID = nullptr;
306
307 const bool success = sdbusplus::unpackPropertiesNoThrow(
308 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
309
310 if (!success)
311 {
312 messages::internalError(asyncResp->res);
313 return;
314 }
315
316 if (uUID != nullptr)
317 {
318 std::string valueStr = *uUID;
319 if (valueStr.size() == 32)
320 {
321 valueStr.insert(8, 1, '-');
322 valueStr.insert(13, 1, '-');
323 valueStr.insert(18, 1, '-');
324 valueStr.insert(23, 1, '-');
325 }
326 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
327 asyncResp->res.jsonValue["UUID"] = valueStr;
328 }
329}
330
331inline void
332 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
333 const boost::system::error_code& ec,
334 const dbus::utility::DBusPropertiesMap& propertiesList)
335{
336 if (ec)
337 {
338 // doesn't have to include this
339 // interface
340 return;
341 }
342 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
343
344 const std::string* partNumber = nullptr;
345 const std::string* serialNumber = nullptr;
346 const std::string* manufacturer = nullptr;
347 const std::string* model = nullptr;
348 const std::string* subModel = nullptr;
349
350 const bool success = sdbusplus::unpackPropertiesNoThrow(
351 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
352 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
353 "Model", model, "SubModel", subModel);
354
355 if (!success)
356 {
357 messages::internalError(asyncResp->res);
358 return;
359 }
360
361 if (partNumber != nullptr)
362 {
363 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
364 }
365
366 if (serialNumber != nullptr)
367 {
368 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
369 }
370
371 if (manufacturer != nullptr)
372 {
373 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
374 }
375
376 if (model != nullptr)
377 {
378 asyncResp->res.jsonValue["Model"] = *model;
379 }
380
381 if (subModel != nullptr)
382 {
383 asyncResp->res.jsonValue["SubModel"] = *subModel;
384 }
385
386 // Grab the bios version
387 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
388 "BiosVersion", false);
389}
390
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400391inline void afterGetAssetTag(
392 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
393 const boost::system::error_code& ec, const std::string& value)
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500394{
395 if (ec)
396 {
397 // doesn't have to include this
398 // interface
399 return;
400 }
401
402 asyncResp->res.jsonValue["AssetTag"] = value;
403}
404
405inline void afterSystemGetSubTree(
406 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500407 const boost::system::error_code& ec,
408 const dbus::utility::MapperGetSubTreeResponse& subtree)
409{
410 if (ec)
411 {
412 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
413 messages::internalError(asyncResp->res);
414 return;
415 }
416 // Iterate over all retrieved ObjectPaths.
417 for (const std::pair<
418 std::string,
419 std::vector<std::pair<std::string, std::vector<std::string>>>>&
420 object : subtree)
421 {
422 const std::string& path = object.first;
423 BMCWEB_LOG_DEBUG("Got path: {}", path);
424 const std::vector<std::pair<std::string, std::vector<std::string>>>&
425 connectionNames = object.second;
426 if (connectionNames.empty())
427 {
428 continue;
429 }
430
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500431 // This is not system, so check if it's cpu, dimm, UUID or
432 // BiosVer
433 for (const auto& connection : connectionNames)
434 {
435 for (const auto& interfaceName : connection.second)
436 {
437 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
438 {
439 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
440
441 getMemorySummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500442 }
443 else if (interfaceName ==
444 "xyz.openbmc_project.Inventory.Item.Cpu")
445 {
446 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
447
448 getProcessorSummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500449 }
450 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
451 {
452 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
453
Ed Tanousdeae6a72024-11-11 21:58:57 -0800454 dbus::utility::getAllProperties(
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500455 *crow::connections::systemBus, connection.first, path,
456 "xyz.openbmc_project.Common.UUID",
457 [asyncResp](const boost::system::error_code& ec3,
458 const dbus::utility::DBusPropertiesMap&
459 properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400460 afterGetUUID(asyncResp, ec3, properties);
461 });
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500462 }
463 else if (interfaceName ==
464 "xyz.openbmc_project.Inventory.Item.System")
465 {
Ed Tanousdeae6a72024-11-11 21:58:57 -0800466 dbus::utility::getAllProperties(
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500467 *crow::connections::systemBus, connection.first, path,
468 "xyz.openbmc_project.Inventory.Decorator.Asset",
469 [asyncResp](const boost::system::error_code& ec3,
470 const dbus::utility::DBusPropertiesMap&
471 properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400472 afterGetInventory(asyncResp, ec3, properties);
473 });
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500474
Ed Tanousdeae6a72024-11-11 21:58:57 -0800475 dbus::utility::getProperty<std::string>(
476 connection.first, path,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500477 "xyz.openbmc_project.Inventory.Decorator."
478 "AssetTag",
479 "AssetTag",
480 std::bind_front(afterGetAssetTag, asyncResp));
481 }
482 }
483 }
484 }
485}
486
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500487/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700488 * @brief Retrieves computer system properties over dbus
489 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700490 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ed Tanous6c34de42018-08-29 13:37:36 -0700491 *
492 * @return None.
493 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700494inline void
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500495 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700496{
Ed Tanous62598e32023-07-17 17:06:25 -0700497 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800498 constexpr std::array<std::string_view, 5> interfaces = {
499 "xyz.openbmc_project.Inventory.Decorator.Asset",
500 "xyz.openbmc_project.Inventory.Item.Cpu",
501 "xyz.openbmc_project.Inventory.Item.Dimm",
502 "xyz.openbmc_project.Inventory.Item.System",
503 "xyz.openbmc_project.Common.UUID",
504 };
505 dbus::utility::getSubTree(
506 "/xyz/openbmc_project/inventory", 0, interfaces,
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500507 std::bind_front(afterSystemGetSubTree, asyncResp));
Ed Tanous6c34de42018-08-29 13:37:36 -0700508}
509
510/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700511 * @brief Retrieves host state properties over dbus
512 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700513 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700514 *
515 * @return None.
516 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700517inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700518{
Ed Tanous62598e32023-07-17 17:06:25 -0700519 BMCWEB_LOG_DEBUG("Get host information.");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800520 dbus::utility::getProperty<std::string>(
521 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
522 "xyz.openbmc_project.State.Host", "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700523 [asyncResp](const boost::system::error_code& ec,
524 const std::string& hostState) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400525 if (ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700526 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400527 if (ec == boost::system::errc::host_unreachable)
528 {
529 // Service not available, no error, just don't return
530 // host state info
531 BMCWEB_LOG_DEBUG("Service not available {}", ec);
532 return;
533 }
534 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
535 messages::internalError(asyncResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700536 return;
537 }
Ed Tanous66173382018-08-15 18:20:59 -0700538
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400539 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
540 // Verify Host State
541 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
542 {
543 asyncResp->res.jsonValue["PowerState"] =
544 resource::PowerState::On;
545 asyncResp->res.jsonValue["Status"]["State"] =
546 resource::State::Enabled;
547 }
548 else if (hostState ==
549 "xyz.openbmc_project.State.Host.HostState.Quiesced")
550 {
551 asyncResp->res.jsonValue["PowerState"] =
552 resource::PowerState::On;
553 asyncResp->res.jsonValue["Status"]["State"] =
554 resource::State::Quiesced;
555 }
556 else if (hostState ==
557 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
558 {
559 asyncResp->res.jsonValue["PowerState"] =
560 resource::PowerState::On;
561 asyncResp->res.jsonValue["Status"]["State"] =
562 resource::State::InTest;
563 }
564 else if (
565 hostState ==
566 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
567 {
568 asyncResp->res.jsonValue["PowerState"] =
569 resource::PowerState::PoweringOn;
570 asyncResp->res.jsonValue["Status"]["State"] =
571 resource::State::Starting;
572 }
573 else if (
574 hostState ==
575 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
576 {
577 asyncResp->res.jsonValue["PowerState"] =
578 resource::PowerState::PoweringOff;
579 asyncResp->res.jsonValue["Status"]["State"] =
580 resource::State::Disabled;
581 }
582 else
583 {
584 asyncResp->res.jsonValue["PowerState"] =
585 resource::PowerState::Off;
586 asyncResp->res.jsonValue["Status"]["State"] =
587 resource::State::Disabled;
588 }
589 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700590}
591
592/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500593 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530594 *
595 * @param[in] dbusSource The boot source in DBUS speak.
596 *
597 * @return Returns as a string, the boot source in Redfish terms. If translation
598 * cannot be done, returns an empty string.
599 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000600inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530601{
602 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
603 {
604 return "None";
605 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700606 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530607 {
608 return "Hdd";
609 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700610 if (dbusSource ==
611 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530612 {
613 return "Cd";
614 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700615 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530616 {
617 return "Pxe";
618 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700619 if (dbusSource ==
620 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700621 {
622 return "Usb";
623 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700624 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530625}
626
627/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300628 * @brief Translates boot type DBUS property value to redfish.
629 *
630 * @param[in] dbusType The boot type in DBUS speak.
631 *
632 * @return Returns as a string, the boot type in Redfish terms. If translation
633 * cannot be done, returns an empty string.
634 */
635inline std::string dbusToRfBootType(const std::string& dbusType)
636{
637 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
638 {
639 return "Legacy";
640 }
641 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
642 {
643 return "UEFI";
644 }
645 return "";
646}
647
648/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500649 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530650 *
651 * @param[in] dbusMode The boot mode in DBUS speak.
652 *
653 * @return Returns as a string, the boot mode in Redfish terms. If translation
654 * cannot be done, returns an empty string.
655 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000656inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530657{
658 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
659 {
660 return "None";
661 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700662 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530663 {
664 return "Diags";
665 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700666 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530667 {
668 return "BiosSetup";
669 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700670 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530671}
672
673/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600674 * @brief Translates boot progress DBUS property value to redfish.
675 *
676 * @param[in] dbusBootProgress The boot progress in DBUS speak.
677 *
678 * @return Returns as a string, the boot progress in Redfish terms. If
679 * translation cannot be done, returns "None".
680 */
681inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
682{
683 // Now convert the D-Bus BootProgress to the appropriate Redfish
684 // enum
685 std::string rfBpLastState = "None";
686 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
687 "ProgressStages.Unspecified")
688 {
689 rfBpLastState = "None";
690 }
691 else if (dbusBootProgress ==
692 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
693 "PrimaryProcInit")
694 {
695 rfBpLastState = "PrimaryProcessorInitializationStarted";
696 }
697 else if (dbusBootProgress ==
698 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
699 "BusInit")
700 {
701 rfBpLastState = "BusInitializationStarted";
702 }
703 else if (dbusBootProgress ==
704 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
705 "MemoryInit")
706 {
707 rfBpLastState = "MemoryInitializationStarted";
708 }
709 else if (dbusBootProgress ==
710 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
711 "SecondaryProcInit")
712 {
713 rfBpLastState = "SecondaryProcessorInitializationStarted";
714 }
715 else if (dbusBootProgress ==
716 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
717 "PCIInit")
718 {
719 rfBpLastState = "PCIResourceConfigStarted";
720 }
721 else if (dbusBootProgress ==
722 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
723 "SystemSetup")
724 {
725 rfBpLastState = "SetupEntered";
726 }
727 else if (dbusBootProgress ==
728 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
729 "SystemInitComplete")
730 {
731 rfBpLastState = "SystemHardwareInitializationComplete";
732 }
733 else if (dbusBootProgress ==
734 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
735 "OSStart")
736 {
737 rfBpLastState = "OSBootStarted";
738 }
739 else if (dbusBootProgress ==
740 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
741 "OSRunning")
742 {
743 rfBpLastState = "OSRunning";
744 }
745 else
746 {
Ed Tanous62598e32023-07-17 17:06:25 -0700747 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600748 // Just return the default
749 }
750 return rfBpLastState;
751}
752
753/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500754 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530755 *
756 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700757 * @param[out] bootSource The DBus source
758 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530759 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700760 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530761 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400762inline int assignBootParameters(
763 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
764 const std::string& rfSource, std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530765{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300766 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
767 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700768
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530769 if (rfSource == "None")
770 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700771 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530772 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700773 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530774 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700775 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
776 }
777 else if (rfSource == "Hdd")
778 {
779 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
780 }
781 else if (rfSource == "Diags")
782 {
783 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
784 }
785 else if (rfSource == "Cd")
786 {
787 bootSource =
788 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
789 }
790 else if (rfSource == "BiosSetup")
791 {
792 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530793 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700794 else if (rfSource == "Usb")
795 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700796 bootSource =
797 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700798 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530799 else
800 {
Ed Tanous62598e32023-07-17 17:06:25 -0700801 BMCWEB_LOG_DEBUG(
802 "Invalid property value for BootSourceOverrideTarget: {}",
803 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700804 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700805 "BootSourceTargetOverride");
806 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530807 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700808 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530809}
Ali Ahmed19817712021-06-29 17:01:52 -0500810
Andrew Geissler978b8802020-11-19 13:36:40 -0600811/**
812 * @brief Retrieves boot progress of the system
813 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700814 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600815 *
816 * @return None.
817 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700818inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600819{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800820 dbus::utility::getProperty<std::string>(
821 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700822 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700823 [asyncResp](const boost::system::error_code& ec,
824 const std::string& bootProgressStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400825 if (ec)
826 {
827 // BootProgress is an optional object so just do nothing if
828 // not found
829 return;
830 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600831
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400832 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600833
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400834 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
835 dbusToRfBootProgress(bootProgressStr);
836 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600837}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838
839/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000840 * @brief Retrieves boot progress Last Update of the system
841 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700842 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000843 *
844 * @return None.
845 */
846inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700847 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000848{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800849 dbus::utility::getProperty<uint64_t>(
850 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000851 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700852 [asyncResp](const boost::system::error_code& ec,
853 const uint64_t lastStateTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400854 if (ec)
855 {
856 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
857 return;
858 }
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000859
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400860 // BootProgressLastUpdate is the last time the BootProgress property
861 // was updated. The time is the Epoch time, number of microseconds
862 // since 1 Jan 1970 00::00::00 UTC."
863 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
864 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000865
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400866 // Convert to ISO 8601 standard
867 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
868 redfish::time_utils::getDateTimeUintUs(lastStateTime);
869 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000870}
871
872/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300873 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300874 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700875 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300876 *
877 * @return None.
878 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300879
Ed Tanousac106bf2023-06-07 09:24:59 -0700880inline void
881 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300882{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800883 dbus::utility::getProperty<std::string>(
884 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700885 "/xyz/openbmc_project/control/host0/boot",
886 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700887 [asyncResp](const boost::system::error_code& ec,
888 const std::string& bootType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400889 if (ec)
890 {
891 // not an error, don't have to have the interface
892 return;
893 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300894
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400895 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300896
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400897 asyncResp->res
898 .jsonValue["Boot"]
899 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
900 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300901
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400902 auto rfType = dbusToRfBootType(bootType);
903 if (rfType.empty())
904 {
905 messages::internalError(asyncResp->res);
906 return;
907 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300908
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400909 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
910 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300911}
912
913/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300914 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530915 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700916 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530917 *
918 * @return None.
919 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300920
Ed Tanousac106bf2023-06-07 09:24:59 -0700921inline void
922 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530923{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800924 dbus::utility::getProperty<std::string>(
925 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700926 "/xyz/openbmc_project/control/host0/boot",
927 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700928 [asyncResp](const boost::system::error_code& ec,
929 const std::string& bootModeStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400930 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530931 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400932 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
933 messages::internalError(asyncResp->res);
934 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530935 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400936
937 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
938
939 nlohmann::json::array_t allowed;
940 allowed.emplace_back("None");
941 allowed.emplace_back("Pxe");
942 allowed.emplace_back("Hdd");
943 allowed.emplace_back("Cd");
944 allowed.emplace_back("Diags");
945 allowed.emplace_back("BiosSetup");
946 allowed.emplace_back("Usb");
947
948 asyncResp->res
949 .jsonValue["Boot"]
950 ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
951 std::move(allowed);
952 if (bootModeStr !=
953 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
954 {
955 auto rfMode = dbusToRfBootMode(bootModeStr);
956 if (!rfMode.empty())
957 {
958 asyncResp->res
959 .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
960 }
961 }
962 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530963}
964
965/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300966 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530967 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700968 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530969 *
970 * @return None.
971 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300972
973inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700974 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530975{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800976 dbus::utility::getProperty<std::string>(
977 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700978 "/xyz/openbmc_project/control/host0/boot",
979 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -0700980 [asyncResp](const boost::system::error_code& ec,
981 const std::string& bootSourceStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400982 if (ec)
Nan Zhou5ef735c2022-06-22 05:24:21 +0000983 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400984 if (ec.value() == boost::asio::error::host_unreachable)
985 {
986 return;
987 }
988 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
989 messages::internalError(asyncResp->res);
Nan Zhou5ef735c2022-06-22 05:24:21 +0000990 return;
991 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530992
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400993 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530994
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400995 auto rfSource = dbusToRfBootSource(bootSourceStr);
996 if (!rfSource.empty())
997 {
998 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
999 rfSource;
1000 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001001
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001002 // Get BootMode as BootSourceOverrideTarget is constructed
1003 // from both BootSource and BootMode
1004 getBootOverrideMode(asyncResp);
1005 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301006}
1007
1008/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001009 * @brief This functions abstracts all the logic behind getting a
1010 * "BootSourceOverrideEnabled" property from an overall boot override enable
1011 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301012 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001013 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301014 *
1015 * @return None.
1016 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301017
Ed Tanousac106bf2023-06-07 09:24:59 -07001018inline void processBootOverrideEnable(
1019 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1020 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001021{
1022 if (!bootOverrideEnableSetting)
1023 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001024 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1025 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001026 return;
1027 }
1028
1029 // If boot source override is enabled, we need to check 'one_time'
1030 // property to set a correct value for the "BootSourceOverrideEnabled"
Ed Tanousdeae6a72024-11-11 21:58:57 -08001031 dbus::utility::getProperty<bool>(
1032 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001033 "/xyz/openbmc_project/control/host0/boot/one_time",
1034 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001035 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001036 if (ec)
1037 {
1038 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1039 messages::internalError(asyncResp->res);
1040 return;
1041 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301042
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001043 if (oneTimeSetting)
1044 {
1045 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1046 "Once";
1047 }
1048 else
1049 {
1050 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1051 "Continuous";
1052 }
1053 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301054}
1055
1056/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001057 * @brief Retrieves boot override enable over DBUS
1058 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001059 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001060 *
1061 * @return None.
1062 */
1063
1064inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001065 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001066{
Ed Tanousdeae6a72024-11-11 21:58:57 -08001067 dbus::utility::getProperty<bool>(
1068 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001069 "/xyz/openbmc_project/control/host0/boot",
1070 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001071 [asyncResp](const boost::system::error_code& ec,
1072 const bool bootOverrideEnable) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001073 if (ec)
Nan Zhou5ef735c2022-06-22 05:24:21 +00001074 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001075 if (ec.value() == boost::asio::error::host_unreachable)
1076 {
1077 return;
1078 }
1079 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1080 messages::internalError(asyncResp->res);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001081 return;
1082 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001083
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001084 processBootOverrideEnable(asyncResp, bootOverrideEnable);
1085 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001086}
1087
1088/**
1089 * @brief Retrieves boot source override properties
1090 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001091 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001092 *
1093 * @return None.
1094 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001095inline void
1096 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001097{
Ed Tanous62598e32023-07-17 17:06:25 -07001098 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001099
Ed Tanousac106bf2023-06-07 09:24:59 -07001100 getBootOverrideSource(asyncResp);
1101 getBootOverrideType(asyncResp);
1102 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001103}
1104
1105/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001106 * @brief Retrieves the Last Reset Time
1107 *
1108 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1109 * and power off. Even though this is the "system" Redfish object look at the
1110 * chassis D-Bus interface for the LastStateChangeTime since this has the
1111 * last power operation time.
1112 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001113 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001114 *
1115 * @return None.
1116 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001117inline void
1118 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001119{
Ed Tanous62598e32023-07-17 17:06:25 -07001120 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001121
Ed Tanousdeae6a72024-11-11 21:58:57 -08001122 dbus::utility::getProperty<uint64_t>(
1123 "xyz.openbmc_project.State.Chassis",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001124 "/xyz/openbmc_project/state/chassis0",
1125 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001126 [asyncResp](const boost::system::error_code& ec,
1127 uint64_t lastResetTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001128 if (ec)
1129 {
1130 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1131 return;
1132 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001133
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001134 // LastStateChangeTime is epoch time, in milliseconds
1135 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1136 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001137
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001138 // Convert to ISO 8601 standard
1139 asyncResp->res.jsonValue["LastResetTime"] =
1140 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
1141 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001142}
1143
1144/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001145 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1146 *
1147 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1148 * corresponding property "AttemptsLeft" that keeps track of the amount of
1149 * automatic retry attempts left are hosted in phosphor-state-manager through
1150 * dbus.
1151 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001152 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001153 *
1154 * @return None.
1155 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001156inline void getAutomaticRebootAttempts(
1157 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001158{
Ed Tanous62598e32023-07-17 17:06:25 -07001159 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001160
Ed Tanousdeae6a72024-11-11 21:58:57 -08001161 dbus::utility::getAllProperties(
1162 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001163 "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) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001167 if (ec)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001168 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001169 if (ec.value() != EBADR)
1170 {
1171 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1172 messages::internalError(asyncResp->res);
1173 }
1174 return;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001175 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001176
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001177 const uint32_t* attemptsLeft = nullptr;
1178 const uint32_t* retryAttempts = nullptr;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001179
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001180 const bool success = sdbusplus::unpackPropertiesNoThrow(
1181 dbus_utils::UnpackErrorPrinter(), propertiesList,
1182 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001183
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001184 if (!success)
1185 {
1186 messages::internalError(asyncResp->res);
1187 return;
1188 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001189
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001190 if (attemptsLeft != nullptr)
1191 {
1192 asyncResp->res
1193 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1194 *attemptsLeft;
1195 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001196
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001197 if (retryAttempts != nullptr)
1198 {
1199 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1200 *retryAttempts;
1201 }
1202 });
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
Ed Tanousdeae6a72024-11-11 21:58:57 -08001217 dbus::utility::getProperty<bool>(
1218 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001219 "/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) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001223 if (ec)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001224 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001225 if (ec.value() != EBADR)
1226 {
1227 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1228 messages::internalError(asyncResp->res);
1229 }
1230 return;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001231 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001232
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001233 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1234 if (autoRebootEnabled)
1235 {
1236 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1237 "RetryAttempts";
1238 }
1239 else
1240 {
1241 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1242 "Disabled";
1243 }
1244 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001245
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001246 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1247 // and RetryAttempts. OpenBMC only supports Disabled and
1248 // RetryAttempts.
1249 nlohmann::json::array_t allowed;
1250 allowed.emplace_back("Disabled");
1251 allowed.emplace_back("RetryAttempts");
1252 asyncResp->res
1253 .jsonValue["Boot"]
1254 ["AutomaticRetryConfig@Redfish.AllowableValues"] =
1255 std::move(allowed);
1256 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001257}
1258
1259/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001260 * @brief Sets RetryAttempts
1261 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001262 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001263 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1264 *
1265 *@return None.
1266 */
1267
Ed Tanousac106bf2023-06-07 09:24:59 -07001268inline void setAutomaticRetryAttempts(
1269 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1270 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001271{
Ed Tanous62598e32023-07-17 17:06:25 -07001272 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001273 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301274 asyncResp, "Boot/AutomaticRetryAttempts",
1275 "xyz.openbmc_project.State.Host",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001276 sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
Corey Hardesty797d5da2022-04-26 17:54:52 +08001277 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
Ginu Georgee93abac2024-06-14 17:35:27 +05301278 retryAttempts);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001279}
1280
Ed Tanous8d69c662023-06-21 10:29:06 -07001281inline computer_system::PowerRestorePolicyTypes
1282 redfishPowerRestorePolicyFromDbus(std::string_view value)
1283{
1284 if (value ==
1285 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1286 {
1287 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1288 }
1289 if (value ==
1290 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1291 {
1292 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1293 }
1294 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001295 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001296 {
1297 return computer_system::PowerRestorePolicyTypes::LastState;
1298 }
1299 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1300 {
1301 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1302 }
1303 return computer_system::PowerRestorePolicyTypes::Invalid;
1304}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001305/**
George Liuc6a620f2020-04-10 17:18:11 +08001306 * @brief Retrieves power restore policy over DBUS.
1307 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001308 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001309 *
1310 * @return None.
1311 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001312inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001313 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001314{
Ed Tanous62598e32023-07-17 17:06:25 -07001315 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001316
Ed Tanousdeae6a72024-11-11 21:58:57 -08001317 dbus::utility::getProperty<std::string>(
1318 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001319 "/xyz/openbmc_project/control/host0/power_restore_policy",
1320 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001321 [asyncResp](const boost::system::error_code& ec,
1322 const std::string& policy) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001323 if (ec)
1324 {
1325 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1326 return;
1327 }
1328 computer_system::PowerRestorePolicyTypes restore =
1329 redfishPowerRestorePolicyFromDbus(policy);
1330 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1331 {
1332 messages::internalError(asyncResp->res);
1333 return;
1334 }
George Liuc6a620f2020-04-10 17:18:11 +08001335
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001336 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
1337 });
George Liuc6a620f2020-04-10 17:18:11 +08001338}
1339
1340/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001341 * @brief Stop Boot On Fault over DBUS.
1342 *
1343 * @param[in] asyncResp Shared pointer for generating response message.
1344 *
1345 * @return None.
1346 */
1347inline void
1348 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1349{
Ed Tanous62598e32023-07-17 17:06:25 -07001350 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001351
Ed Tanousdeae6a72024-11-11 21:58:57 -08001352 dbus::utility::getProperty<bool>(
1353 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001354 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1355 [asyncResp](const boost::system::error_code& ec, bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001356 if (ec)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001357 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001358 if (ec.value() != EBADR)
1359 {
1360 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1361 messages::internalError(asyncResp->res);
1362 }
1363 return;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001364 }
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001365
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001366 if (value)
1367 {
1368 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1369 computer_system::StopBootOnFault::AnyFault;
1370 }
1371 else
1372 {
1373 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1374 computer_system::StopBootOnFault::Never;
1375 }
1376 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001377}
1378
1379/**
Ali Ahmed19817712021-06-29 17:01:52 -05001380 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1381 * TPM is required for booting the host.
1382 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001383 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001384 *
1385 * @return None.
1386 */
1387inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001388 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001389{
Ed Tanous62598e32023-07-17 17:06:25 -07001390 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001391 constexpr std::array<std::string_view, 1> interfaces = {
1392 "xyz.openbmc_project.Control.TPM.Policy"};
1393 dbus::utility::getSubTree(
1394 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001395 [asyncResp](const boost::system::error_code& ec,
1396 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001397 if (ec)
Ali Ahmed19817712021-06-29 17:01:52 -05001398 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001399 BMCWEB_LOG_DEBUG(
1400 "DBUS response error on TPM.Policy GetSubTree{}", ec);
1401 // This is an optional D-Bus object so just return if
1402 // error occurs
1403 return;
1404 }
1405 if (subtree.empty())
1406 {
1407 // As noted above, this is an optional interface so just return
1408 // if there is no instance found
1409 return;
1410 }
1411
1412 /* When there is more than one TPMEnable object... */
1413 if (subtree.size() > 1)
1414 {
1415 BMCWEB_LOG_DEBUG(
1416 "DBUS response has more than 1 TPM Enable object:{}",
1417 subtree.size());
1418 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001419 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001420 return;
1421 }
1422
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001423 // Make sure the Dbus response map has a service and objectPath
1424 // field
1425 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
Ali Ahmed19817712021-06-29 17:01:52 -05001426 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001427 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1428 messages::internalError(asyncResp->res);
1429 return;
Ali Ahmed19817712021-06-29 17:01:52 -05001430 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001431
1432 const std::string& path = subtree[0].first;
1433 const std::string& serv = subtree[0].second.begin()->first;
1434
1435 // Valid TPM Enable object found, now reading the current value
Ed Tanousdeae6a72024-11-11 21:58:57 -08001436 dbus::utility::getProperty<bool>(
1437 serv, path, "xyz.openbmc_project.Control.TPM.Policy",
1438 "TPMEnable",
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001439 [asyncResp](const boost::system::error_code& ec2,
1440 bool tpmRequired) {
1441 if (ec2)
1442 {
1443 BMCWEB_LOG_ERROR(
1444 "D-BUS response error on TPM.Policy Get{}", ec2);
1445 messages::internalError(asyncResp->res);
1446 return;
1447 }
1448
1449 if (tpmRequired)
1450 {
1451 asyncResp->res
1452 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1453 "Required";
1454 }
1455 else
1456 {
1457 asyncResp->res
1458 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1459 "Disabled";
1460 }
1461 });
George Liue99073f2022-12-09 11:06:16 +08001462 });
Ali Ahmed19817712021-06-29 17:01:52 -05001463}
1464
1465/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001466 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1467 * TPM is required for booting the host.
1468 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001469 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001470 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1471 *
1472 * @return None.
1473 */
1474inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001475 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001476{
Ed Tanous62598e32023-07-17 17:06:25 -07001477 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001478 constexpr std::array<std::string_view, 1> interfaces = {
1479 "xyz.openbmc_project.Control.TPM.Policy"};
1480 dbus::utility::getSubTree(
1481 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001482 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001483 tpmRequired](const boost::system::error_code& ec,
1484 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001485 if (ec)
1486 {
1487 BMCWEB_LOG_ERROR(
1488 "DBUS response error on TPM.Policy GetSubTree{}", ec);
1489 messages::internalError(asyncResp->res);
1490 return;
1491 }
1492 if (subtree.empty())
1493 {
1494 messages::propertyValueNotInList(asyncResp->res,
1495 "ComputerSystem",
1496 "TrustedModuleRequiredToBoot");
1497 return;
1498 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001499
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001500 /* When there is more than one TPMEnable object... */
1501 if (subtree.size() > 1)
1502 {
1503 BMCWEB_LOG_DEBUG(
1504 "DBUS response has more than 1 TPM Enable object:{}",
1505 subtree.size());
1506 // Throw an internal Error and return
1507 messages::internalError(asyncResp->res);
1508 return;
1509 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001510
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001511 // Make sure the Dbus response map has a service and objectPath
1512 // field
1513 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1514 {
1515 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1516 messages::internalError(asyncResp->res);
1517 return;
1518 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001519
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001520 const std::string& path = subtree[0].first;
1521 const std::string& serv = subtree[0].second.begin()->first;
Ed Tanous002d39b2022-05-31 08:59:27 -07001522
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001523 if (serv.empty())
1524 {
1525 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1526 messages::internalError(asyncResp->res);
1527 return;
1528 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001529
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001530 // Valid TPM Enable object found, now setting the value
1531 setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1532 path, "xyz.openbmc_project.Control.TPM.Policy",
1533 "TPMEnable", tpmRequired);
1534 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001535}
1536
1537/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301538 * @brief Sets boot properties into DBUS object(s).
1539 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001540 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001541 * @param[in] bootType The boot type to set.
1542 * @return Integer error code.
1543 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001544inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001545 const std::optional<std::string>& bootType)
1546{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001547 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001548
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001549 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001550 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001551 return;
1552 }
1553
1554 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001555 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001556 // Figure out which DBUS interface and property to use
1557 if (*bootType == "Legacy")
1558 {
1559 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1560 }
1561 else if (*bootType == "UEFI")
1562 {
1563 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1564 }
1565 else
1566 {
Ed Tanous62598e32023-07-17 17:06:25 -07001567 BMCWEB_LOG_DEBUG("Invalid property value for "
1568 "BootSourceOverrideMode: {}",
1569 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001570 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001571 "BootSourceOverrideMode");
1572 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001573 }
1574
1575 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001576 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001577
Ginu Georgee93abac2024-06-14 17:35:27 +05301578 setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1579 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001580 sdbusplus::message::object_path(
1581 "/xyz/openbmc_project/control/host0/boot"),
1582 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ginu Georgee93abac2024-06-14 17:35:27 +05301583 bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001584}
1585
1586/**
1587 * @brief Sets boot properties into DBUS object(s).
1588 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001589 * @param[in] asyncResp Shared pointer for generating response
1590 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001591 * @param[in] bootType The boot type to set.
1592 * @return Integer error code.
1593 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001594inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001595 const std::optional<std::string>& bootEnable)
1596{
1597 if (!bootEnable)
1598 {
1599 return;
1600 }
1601 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001602 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001603
1604 bool bootOverrideEnable = false;
1605 bool bootOverridePersistent = false;
1606 // Figure out which DBUS interface and property to use
1607 if (*bootEnable == "Disabled")
1608 {
1609 bootOverrideEnable = false;
1610 }
1611 else if (*bootEnable == "Once")
1612 {
1613 bootOverrideEnable = true;
1614 bootOverridePersistent = false;
1615 }
1616 else if (*bootEnable == "Continuous")
1617 {
1618 bootOverrideEnable = true;
1619 bootOverridePersistent = true;
1620 }
1621 else
1622 {
Ed Tanous62598e32023-07-17 17:06:25 -07001623 BMCWEB_LOG_DEBUG(
1624 "Invalid property value for BootSourceOverrideEnabled: {}",
1625 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001626 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001627 "BootSourceOverrideEnabled");
1628 return;
1629 }
1630
1631 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001632 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001633
Ginu Georgee93abac2024-06-14 17:35:27 +05301634 setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1635 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001636 sdbusplus::message::object_path(
1637 "/xyz/openbmc_project/control/host0/boot"),
1638 "xyz.openbmc_project.Object.Enable", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05301639 bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001640
1641 if (!bootOverrideEnable)
1642 {
1643 return;
1644 }
1645
1646 // In case boot override is enabled we need to set correct value for the
1647 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001648 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1649 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001650
Ginu Georgee93abac2024-06-14 17:35:27 +05301651 setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1652 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001653 sdbusplus::message::object_path(
1654 "/xyz/openbmc_project/control/host0/boot/one_time"),
1655 "xyz.openbmc_project.Object.Enable", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05301656 !bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001657}
1658
1659/**
1660 * @brief Sets boot properties into DBUS object(s).
1661 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001662 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301663 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301664 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001665 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301666 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001667inline void
1668 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1669 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301670{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001671 std::string bootSourceStr;
1672 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001673
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001674 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301675 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001676 return;
1677 }
1678
1679 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001680 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001681 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001682 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1683 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001684 {
Ed Tanous62598e32023-07-17 17:06:25 -07001685 BMCWEB_LOG_DEBUG(
1686 "Invalid property value for BootSourceOverrideTarget: {}",
1687 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001688 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001689 "BootSourceTargetOverride");
1690 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001691 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301692
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001693 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001694 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1695 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001696
Ginu Georgee93abac2024-06-14 17:35:27 +05301697 setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1698 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001699 sdbusplus::message::object_path(
1700 "/xyz/openbmc_project/control/host0/boot"),
1701 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ginu Georgee93abac2024-06-14 17:35:27 +05301702 bootSourceStr);
1703 setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1704 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001705 sdbusplus::message::object_path(
1706 "/xyz/openbmc_project/control/host0/boot"),
1707 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ginu Georgee93abac2024-06-14 17:35:27 +05301708 bootModeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001709}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001710
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001711/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001712 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301713 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001714 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301715 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001716 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301717 * @param[in] bootEnable The boot override enable from incoming RF request.
1718 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001719 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301720 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001721
Ed Tanousac106bf2023-06-07 09:24:59 -07001722inline void
1723 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1724 const std::optional<std::string>& bootSource,
1725 const std::optional<std::string>& bootType,
1726 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301727{
Ed Tanous62598e32023-07-17 17:06:25 -07001728 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301729
Ed Tanousac106bf2023-06-07 09:24:59 -07001730 setBootModeOrSource(asyncResp, bootSource);
1731 setBootType(asyncResp, bootType);
1732 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301733}
1734
George Liuc6a620f2020-04-10 17:18:11 +08001735/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001736 * @brief Sets AssetTag
1737 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001738 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001739 * @param[in] assetTag "AssetTag" from request.
1740 *
1741 * @return None.
1742 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001743inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001744 const std::string& assetTag)
1745{
George Liue99073f2022-12-09 11:06:16 +08001746 constexpr std::array<std::string_view, 1> interfaces = {
1747 "xyz.openbmc_project.Inventory.Item.System"};
1748 dbus::utility::getSubTree(
1749 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001750 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001751 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001752 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001753 if (ec)
1754 {
1755 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1756 messages::internalError(asyncResp->res);
1757 return;
1758 }
1759 if (subtree.empty())
1760 {
1761 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1762 messages::internalError(asyncResp->res);
1763 return;
1764 }
1765 // Assume only 1 system D-Bus object
1766 // Throw an error if there is more than 1
1767 if (subtree.size() > 1)
1768 {
1769 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1770 messages::internalError(asyncResp->res);
1771 return;
1772 }
1773 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1774 {
1775 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1776 messages::internalError(asyncResp->res);
1777 return;
1778 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001779
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001780 const std::string& path = subtree[0].first;
1781 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001782
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001783 if (service.empty())
1784 {
1785 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1786 messages::internalError(asyncResp->res);
1787 return;
1788 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001789
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001790 setDbusProperty(asyncResp, "AssetTag", service, path,
1791 "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1792 "AssetTag", assetTag);
1793 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001794}
1795
1796/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001797 * @brief Validate the specified stopBootOnFault is valid and return the
1798 * stopBootOnFault name associated with that string
1799 *
1800 * @param[in] stopBootOnFaultString String representing the desired
1801 * stopBootOnFault
1802 *
1803 * @return stopBootOnFault value or empty if incoming value is not valid
1804 */
1805inline std::optional<bool>
1806 validstopBootOnFault(const std::string& stopBootOnFaultString)
1807{
1808 if (stopBootOnFaultString == "AnyFault")
1809 {
1810 return true;
1811 }
1812
1813 if (stopBootOnFaultString == "Never")
1814 {
1815 return false;
1816 }
1817
1818 return std::nullopt;
1819}
1820
1821/**
1822 * @brief Sets stopBootOnFault
1823 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001824 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001825 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1826 *
1827 * @return None.
1828 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001829inline void
1830 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1831 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001832{
Ed Tanous62598e32023-07-17 17:06:25 -07001833 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001834
1835 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1836 if (!stopBootEnabled)
1837 {
Ed Tanous62598e32023-07-17 17:06:25 -07001838 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1839 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001840 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001841 "StopBootOnFault");
1842 return;
1843 }
1844
Ginu Georgee93abac2024-06-14 17:35:27 +05301845 setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1846 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001847 sdbusplus::message::object_path(
1848 "/xyz/openbmc_project/logging/settings"),
1849 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
Ginu Georgee93abac2024-06-14 17:35:27 +05301850 *stopBootEnabled);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001851}
1852
1853/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001854 * @brief Sets automaticRetry (Auto Reboot)
1855 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001856 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001857 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1858 *
1859 * @return None.
1860 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001861inline void
1862 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1863 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001864{
Ed Tanous62598e32023-07-17 17:06:25 -07001865 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001866
1867 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001868 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001869
1870 if (automaticRetryConfig == "Disabled")
1871 {
1872 autoRebootEnabled = false;
1873 }
1874 else if (automaticRetryConfig == "RetryAttempts")
1875 {
1876 autoRebootEnabled = true;
1877 }
1878 else
1879 {
Ed Tanous62598e32023-07-17 17:06:25 -07001880 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
1881 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07001882 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001883 "AutomaticRetryConfig");
1884 return;
1885 }
1886
Ginu Georgee93abac2024-06-14 17:35:27 +05301887 setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1888 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001889 sdbusplus::message::object_path(
1890 "/xyz/openbmc_project/control/host0/auto_reboot"),
1891 "xyz.openbmc_project.Control.Boot.RebootPolicy",
Ginu Georgee93abac2024-06-14 17:35:27 +05301892 "AutoReboot", autoRebootEnabled);
Gunnar Mills69f35302020-05-17 16:06:31 -05001893}
1894
Ed Tanous8d69c662023-06-21 10:29:06 -07001895inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1896{
1897 if (policy == "AlwaysOn")
1898 {
1899 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1900 }
1901 if (policy == "AlwaysOff")
1902 {
1903 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1904 }
1905 if (policy == "LastState")
1906 {
1907 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1908 }
1909 return "";
1910}
1911
Gunnar Mills69f35302020-05-17 16:06:31 -05001912/**
George Liuc6a620f2020-04-10 17:18:11 +08001913 * @brief Sets power restore policy properties.
1914 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001915 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001916 * @param[in] policy power restore policy properties from request.
1917 *
1918 * @return None.
1919 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001920inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001921 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001922 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08001923{
Ed Tanous62598e32023-07-17 17:06:25 -07001924 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08001925
Ed Tanous8d69c662023-06-21 10:29:06 -07001926 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001927
Ed Tanous8d69c662023-06-21 10:29:06 -07001928 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08001929 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001930 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06001931 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001932 return;
1933 }
1934
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001935 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301936 asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001937 sdbusplus::message::object_path(
1938 "/xyz/openbmc_project/control/host0/power_restore_policy"),
George Liuc6a620f2020-04-10 17:18:11 +08001939 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ginu Georgee93abac2024-06-14 17:35:27 +05301940 powerRestorePolicy);
George Liuc6a620f2020-04-10 17:18:11 +08001941}
1942
AppaRao Pulia6349912019-10-18 17:16:08 +05301943/**
1944 * @brief Retrieves provisioning status
1945 *
Ed Tanous25b54db2024-04-17 15:40:31 -07001946 * @param[in] asyncResp Shared pointer for completing asynchronous
1947 * calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05301948 *
1949 * @return None.
1950 */
Ed Tanous25b54db2024-04-17 15:40:31 -07001951inline void
1952 getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301953{
Ed Tanous62598e32023-07-17 17:06:25 -07001954 BMCWEB_LOG_DEBUG("Get OEM information.");
Ed Tanousdeae6a72024-11-11 21:58:57 -08001955 dbus::utility::getAllProperties(
1956 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1957 "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07001958 [asyncResp](const boost::system::error_code& ec,
1959 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001960 nlohmann::json& oemPFR =
1961 asyncResp->res
1962 .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1963 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1964 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1965 oemPFR["@odata.type"] =
1966 "#OpenBMCComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07001967
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001968 if (ec)
AppaRao Pulia6349912019-10-18 17:16:08 +05301969 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001970 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1971 // not an error, don't have to have the interface
Ed Tanous539d8c62024-06-19 14:38:27 -07001972 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001973 FirmwareProvisioningStatus::NotProvisioned;
1974 return;
1975 }
1976
1977 const bool* provState = nullptr;
1978 const bool* lockState = nullptr;
1979
1980 const bool success = sdbusplus::unpackPropertiesNoThrow(
1981 dbus_utils::UnpackErrorPrinter(), propertiesList,
1982 "UfmProvisioned", provState, "UfmLocked", lockState);
1983
1984 if (!success)
1985 {
1986 messages::internalError(asyncResp->res);
1987 return;
1988 }
1989
1990 if ((provState == nullptr) || (lockState == nullptr))
1991 {
1992 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
1993 messages::internalError(asyncResp->res);
1994 return;
1995 }
1996
1997 if (*provState)
1998 {
1999 if (*lockState)
2000 {
2001 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2002 FirmwareProvisioningStatus::ProvisionedAndLocked;
2003 }
2004 else
2005 {
2006 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2007 FirmwareProvisioningStatus::ProvisionedButNotLocked;
2008 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302009 }
2010 else
2011 {
Ed Tanous539d8c62024-06-19 14:38:27 -07002012 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002013 FirmwareProvisioningStatus::NotProvisioned;
AppaRao Pulia6349912019-10-18 17:16:08 +05302014 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002015 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302016}
AppaRao Pulia6349912019-10-18 17:16:08 +05302017
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302018/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002019 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002020 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002021 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002022 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002023 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002024 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002025inline computer_system::PowerMode
2026 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002027{
Chris Cainb6655102024-02-01 14:35:33 -06002028 using PowerMode = computer_system::PowerMode;
2029
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002030 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002031 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002032 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002033 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002034 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002035 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002036 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002037 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002038 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002039 if (modeString ==
2040 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002041 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002042 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002043 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002044 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002045 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2046 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002047 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002048 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002049 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002050 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2051 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002052 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002053 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002054 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002055 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2056 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002057 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002058 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002059 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002060 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002061 return PowerMode::OEM;
2062 }
2063 // Any other values would be invalid
2064 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2065 return PowerMode::Invalid;
2066}
2067
2068inline void
2069 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2070 const boost::system::error_code& ec,
2071 const dbus::utility::DBusPropertiesMap& properties)
2072{
2073 if (ec)
2074 {
2075 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2076 messages::internalError(asyncResp->res);
2077 return;
2078 }
2079
2080 std::string powerMode;
2081 const std::vector<std::string>* allowedModes = nullptr;
2082 const bool success = sdbusplus::unpackPropertiesNoThrow(
2083 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2084 "AllowedPowerModes", allowedModes);
2085
2086 if (!success)
2087 {
2088 messages::internalError(asyncResp->res);
2089 return;
2090 }
2091
2092 nlohmann::json::array_t modeList;
2093 if (allowedModes == nullptr)
2094 {
2095 modeList.emplace_back("Static");
2096 modeList.emplace_back("MaximumPerformance");
2097 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002098 }
2099 else
2100 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002101 for (const auto& aMode : *allowedModes)
2102 {
2103 computer_system::PowerMode modeValue =
2104 translatePowerModeString(aMode);
2105 if (modeValue == computer_system::PowerMode::Invalid)
2106 {
2107 messages::internalError(asyncResp->res);
2108 continue;
2109 }
2110 modeList.emplace_back(modeValue);
2111 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002112 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002113 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002114
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002115 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2116 const computer_system::PowerMode modeValue =
2117 translatePowerModeString(powerMode);
2118 if (modeValue == computer_system::PowerMode::Invalid)
2119 {
2120 messages::internalError(asyncResp->res);
2121 return;
2122 }
2123 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2124}
Chris Cain3a2d04242021-05-28 16:57:10 -05002125/**
2126 * @brief Retrieves system power mode
2127 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002128 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002129 *
2130 * @return None.
2131 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002132inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002133{
Ed Tanous62598e32023-07-17 17:06:25 -07002134 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002135
2136 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002137 constexpr std::array<std::string_view, 1> interfaces = {
2138 "xyz.openbmc_project.Control.Power.Mode"};
2139 dbus::utility::getSubTree(
2140 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002141 [asyncResp](const boost::system::error_code& ec,
2142 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002143 if (ec)
2144 {
2145 BMCWEB_LOG_DEBUG(
2146 "DBUS response error on Power.Mode GetSubTree {}", ec);
2147 // This is an optional D-Bus object so just return if
2148 // error occurs
2149 return;
2150 }
2151 if (subtree.empty())
2152 {
2153 // As noted above, this is an optional interface so just return
2154 // if there is no instance found
2155 return;
2156 }
2157 if (subtree.size() > 1)
2158 {
2159 // More then one PowerMode object is not supported and is an
2160 // error
2161 BMCWEB_LOG_DEBUG(
2162 "Found more than 1 system D-Bus Power.Mode objects: {}",
2163 subtree.size());
2164 messages::internalError(asyncResp->res);
2165 return;
2166 }
2167 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2168 {
2169 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2170 messages::internalError(asyncResp->res);
2171 return;
2172 }
2173 const std::string& path = subtree[0].first;
2174 const std::string& service = subtree[0].second.begin()->first;
2175 if (service.empty())
2176 {
2177 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2178 messages::internalError(asyncResp->res);
2179 return;
2180 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002181
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002182 // Valid Power Mode object found, now read the mode properties
Ed Tanousdeae6a72024-11-11 21:58:57 -08002183 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002184 *crow::connections::systemBus, service, path,
2185 "xyz.openbmc_project.Control.Power.Mode",
2186 [asyncResp](
2187 const boost::system::error_code& ec2,
2188 const dbus::utility::DBusPropertiesMap& properties) {
2189 afterGetPowerMode(asyncResp, ec2, properties);
2190 });
George Liue99073f2022-12-09 11:06:16 +08002191 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002192}
2193
2194/**
2195 * @brief Validate the specified mode is valid and return the PowerMode
2196 * name associated with that string
2197 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002198 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002199 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002200 *
2201 * @return PowerMode value or empty string if mode is not valid
2202 */
2203inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002204 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002205 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002206{
Chris Cainb6655102024-02-01 14:35:33 -06002207 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002208 std::string mode;
2209
Chris Cainb6655102024-02-01 14:35:33 -06002210 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002211 {
2212 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2213 }
Chris Cainb6655102024-02-01 14:35:33 -06002214 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002215 {
George Liu0fda0f12021-11-16 10:06:17 +08002216 mode =
2217 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002218 }
Chris Cainb6655102024-02-01 14:35:33 -06002219 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002220 {
2221 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2222 }
Chris Cainb6655102024-02-01 14:35:33 -06002223 else if (modeValue == PowerMode::BalancedPerformance)
2224 {
2225 mode =
2226 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2227 }
2228 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2229 {
2230 mode =
2231 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2232 }
2233 else if (modeValue == PowerMode::EfficiencyFavorPower)
2234 {
2235 mode =
2236 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2237 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002238 else
2239 {
Chris Cainb6655102024-02-01 14:35:33 -06002240 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002241 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002242 }
2243 return mode;
2244}
2245
2246/**
2247 * @brief Sets system power mode.
2248 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002249 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002250 * @param[in] pmode System power mode from request.
2251 *
2252 * @return None.
2253 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002254inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002255 const std::string& pmode)
2256{
Ed Tanous62598e32023-07-17 17:06:25 -07002257 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002258
Ed Tanousac106bf2023-06-07 09:24:59 -07002259 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002260 if (powerMode.empty())
2261 {
2262 return;
2263 }
2264
2265 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002266 constexpr std::array<std::string_view, 1> interfaces = {
2267 "xyz.openbmc_project.Control.Power.Mode"};
2268 dbus::utility::getSubTree(
2269 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002270 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002271 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002272 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002273 if (ec)
2274 {
2275 BMCWEB_LOG_ERROR(
2276 "DBUS response error on Power.Mode GetSubTree {}", ec);
2277 // This is an optional D-Bus object, but user attempted to patch
2278 messages::internalError(asyncResp->res);
2279 return;
2280 }
2281 if (subtree.empty())
2282 {
2283 // This is an optional D-Bus object, but user attempted to patch
2284 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2285 "PowerMode");
2286 return;
2287 }
2288 if (subtree.size() > 1)
2289 {
2290 // More then one PowerMode object is not supported and is an
2291 // error
2292 BMCWEB_LOG_DEBUG(
2293 "Found more than 1 system D-Bus Power.Mode objects: {}",
2294 subtree.size());
2295 messages::internalError(asyncResp->res);
2296 return;
2297 }
2298 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2299 {
2300 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2301 messages::internalError(asyncResp->res);
2302 return;
2303 }
2304 const std::string& path = subtree[0].first;
2305 const std::string& service = subtree[0].second.begin()->first;
2306 if (service.empty())
2307 {
2308 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2309 messages::internalError(asyncResp->res);
2310 return;
2311 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002312
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002313 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002314
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002315 // Set the Power Mode property
2316 setDbusProperty(asyncResp, "PowerMode", service, path,
2317 "xyz.openbmc_project.Control.Power.Mode",
2318 "PowerMode", powerMode);
2319 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002320}
2321
2322/**
Yong Li51709ff2019-09-30 14:13:04 +08002323 * @brief Translates watchdog timeout action DBUS property value to redfish.
2324 *
2325 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2326 *
2327 * @return Returns as a string, the timeout action in Redfish terms. If
2328 * translation cannot be done, returns an empty string.
2329 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002330inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002331{
2332 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2333 {
2334 return "None";
2335 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002336 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002337 {
2338 return "ResetSystem";
2339 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002340 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002341 {
2342 return "PowerDown";
2343 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002344 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002345 {
2346 return "PowerCycle";
2347 }
2348
2349 return "";
2350}
2351
2352/**
Yong Lic45f0082019-10-10 14:19:01 +08002353 *@brief Translates timeout action from Redfish to DBUS property value.
2354 *
2355 *@param[in] rfAction The timeout action in Redfish.
2356 *
2357 *@return Returns as a string, the time_out action as expected by DBUS.
2358 *If translation cannot be done, returns an empty string.
2359 */
2360
Ed Tanous23a21a12020-07-25 04:45:05 +00002361inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002362{
2363 if (rfAction == "None")
2364 {
2365 return "xyz.openbmc_project.State.Watchdog.Action.None";
2366 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002367 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002368 {
2369 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2370 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002371 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002372 {
2373 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2374 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002375 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002376 {
2377 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2378 }
2379
2380 return "";
2381}
2382
2383/**
Yong Li51709ff2019-09-30 14:13:04 +08002384 * @brief Retrieves host watchdog timer properties over DBUS
2385 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002386 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002387 *
2388 * @return None.
2389 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002390inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002391 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002392{
Ed Tanous62598e32023-07-17 17:06:25 -07002393 BMCWEB_LOG_DEBUG("Get host watchodg");
Ed Tanousdeae6a72024-11-11 21:58:57 -08002394 dbus::utility::getAllProperties(
2395 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002396 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002397 [asyncResp](const boost::system::error_code& ec,
2398 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002399 if (ec)
2400 {
2401 // watchdog service is stopped
2402 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2403 return;
2404 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002405
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002406 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002407
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002408 nlohmann::json& hostWatchdogTimer =
2409 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002410
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002411 // watchdog service is running/enabled
2412 hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
Ed Tanous002d39b2022-05-31 08:59:27 -07002413
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002414 const bool* enabled = nullptr;
2415 const std::string* expireAction = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002416
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002417 const bool success = sdbusplus::unpackPropertiesNoThrow(
2418 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2419 enabled, "ExpireAction", expireAction);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002420
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002421 if (!success)
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002422 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002423 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002424 return;
2425 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002426
2427 if (enabled != nullptr)
2428 {
2429 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2430 }
2431
2432 if (expireAction != nullptr)
2433 {
2434 std::string action = dbusToRfWatchdogAction(*expireAction);
2435 if (action.empty())
2436 {
2437 messages::internalError(asyncResp->res);
2438 return;
2439 }
2440 hostWatchdogTimer["TimeoutAction"] = action;
2441 }
2442 });
Yong Li51709ff2019-09-30 14:13:04 +08002443}
2444
2445/**
Yong Lic45f0082019-10-10 14:19:01 +08002446 * @brief Sets Host WatchDog Timer properties.
2447 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002448 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002449 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2450 * RF request.
2451 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2452 *
2453 * @return None.
2454 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002455inline void
2456 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2457 const std::optional<bool> wdtEnable,
2458 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002459{
Ed Tanous62598e32023-07-17 17:06:25 -07002460 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002461
2462 if (wdtTimeOutAction)
2463 {
2464 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2465 // check if TimeOut Action is Valid
2466 if (wdtTimeOutActStr.empty())
2467 {
Ed Tanous62598e32023-07-17 17:06:25 -07002468 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2469 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002470 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002471 "TimeoutAction");
2472 return;
2473 }
2474
Ginu Georgee93abac2024-06-14 17:35:27 +05302475 setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2476 "xyz.openbmc_project.Watchdog",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00002477 sdbusplus::message::object_path(
2478 "/xyz/openbmc_project/watchdog/host0"),
2479 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ginu Georgee93abac2024-06-14 17:35:27 +05302480 wdtTimeOutActStr);
Yong Lic45f0082019-10-10 14:19:01 +08002481 }
2482
2483 if (wdtEnable)
2484 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302485 setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2486 "xyz.openbmc_project.Watchdog",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00002487 sdbusplus::message::object_path(
2488 "/xyz/openbmc_project/watchdog/host0"),
2489 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05302490 *wdtEnable);
Yong Lic45f0082019-10-10 14:19:01 +08002491 }
2492}
2493
Chris Cain37bbf982021-09-20 10:53:09 -05002494/**
2495 * @brief Parse the Idle Power Saver properties into json
2496 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002497 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002498 * @param[in] properties IPS property data from DBus.
2499 *
2500 * @return true if successful
2501 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002502inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002503 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002504 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002505{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002506 const bool* enabled = nullptr;
2507 const uint8_t* enterUtilizationPercent = nullptr;
2508 const uint64_t* enterDwellTime = nullptr;
2509 const uint8_t* exitUtilizationPercent = nullptr;
2510 const uint64_t* exitDwellTime = nullptr;
2511
2512 const bool success = sdbusplus::unpackPropertiesNoThrow(
2513 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002514 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2515 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2516 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002517
2518 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002519 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002520 return false;
2521 }
2522
2523 if (enabled != nullptr)
2524 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002525 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002526 }
2527
2528 if (enterUtilizationPercent != nullptr)
2529 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002530 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002531 *enterUtilizationPercent;
2532 }
2533
2534 if (enterDwellTime != nullptr)
2535 {
2536 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002537 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002538 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2539 .count();
2540 }
2541
2542 if (exitUtilizationPercent != nullptr)
2543 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002544 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002545 *exitUtilizationPercent;
2546 }
2547
2548 if (exitDwellTime != nullptr)
2549 {
2550 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002551 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002552 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2553 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002554 }
2555
2556 return true;
2557}
2558
2559/**
2560 * @brief Retrieves host watchdog timer properties over DBUS
2561 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002562 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002563 *
2564 * @return None.
2565 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002566inline void
2567 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002568{
Ed Tanous62598e32023-07-17 17:06:25 -07002569 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002570
2571 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002572 constexpr std::array<std::string_view, 1> interfaces = {
2573 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2574 dbus::utility::getSubTree(
2575 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002576 [asyncResp](const boost::system::error_code& ec,
2577 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002578 if (ec)
Chris Cain37bbf982021-09-20 10:53:09 -05002579 {
Ed Tanous62598e32023-07-17 17:06:25 -07002580 BMCWEB_LOG_ERROR(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002581 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2582 ec);
2583 messages::internalError(asyncResp->res);
2584 return;
2585 }
2586 if (subtree.empty())
2587 {
2588 // This is an optional interface so just return
2589 // if there is no instance found
2590 BMCWEB_LOG_DEBUG("No instances found");
2591 return;
2592 }
2593 if (subtree.size() > 1)
2594 {
2595 // More then one PowerIdlePowerSaver object is not supported and
2596 // is an error
2597 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2598 "Power.IdlePowerSaver objects: {}",
2599 subtree.size());
2600 messages::internalError(asyncResp->res);
2601 return;
2602 }
2603 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2604 {
2605 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2606 messages::internalError(asyncResp->res);
2607 return;
2608 }
2609 const std::string& path = subtree[0].first;
2610 const std::string& service = subtree[0].second.begin()->first;
2611 if (service.empty())
2612 {
2613 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002614 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002615 return;
2616 }
2617
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002618 // Valid IdlePowerSaver object found, now read the current values
Ed Tanousdeae6a72024-11-11 21:58:57 -08002619 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002620 *crow::connections::systemBus, service, path,
2621 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2622 [asyncResp](
2623 const boost::system::error_code& ec2,
2624 const dbus::utility::DBusPropertiesMap& properties) {
2625 if (ec2)
2626 {
2627 BMCWEB_LOG_ERROR(
2628 "DBUS response error on IdlePowerSaver GetAll: {}",
2629 ec2);
2630 messages::internalError(asyncResp->res);
2631 return;
2632 }
2633
2634 if (!parseIpsProperties(asyncResp, properties))
2635 {
2636 messages::internalError(asyncResp->res);
2637 return;
2638 }
2639 });
George Liue99073f2022-12-09 11:06:16 +08002640 });
Chris Cain37bbf982021-09-20 10:53:09 -05002641
Ed Tanous62598e32023-07-17 17:06:25 -07002642 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002643}
2644
2645/**
2646 * @brief Sets Idle Power Saver properties.
2647 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002648 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002649 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2650 * RF request.
2651 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2652 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2653 * before entering idle state.
2654 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2655 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2656 * before exiting idle state
2657 *
2658 * @return None.
2659 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002660inline void setIdlePowerSaver(
2661 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2662 const std::optional<bool> ipsEnable,
2663 const std::optional<uint8_t> ipsEnterUtil,
2664 const std::optional<uint64_t> ipsEnterTime,
2665 const std::optional<uint8_t> ipsExitUtil,
2666 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002667{
Ed Tanous62598e32023-07-17 17:06:25 -07002668 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002669
2670 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002671 constexpr std::array<std::string_view, 1> interfaces = {
2672 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2673 dbus::utility::getSubTree(
2674 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002675 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002676 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002677 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002678 if (ec)
2679 {
2680 BMCWEB_LOG_ERROR(
2681 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2682 ec);
2683 messages::internalError(asyncResp->res);
2684 return;
2685 }
2686 if (subtree.empty())
2687 {
2688 // This is an optional D-Bus object, but user attempted to patch
2689 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2690 "IdlePowerSaver");
2691 return;
2692 }
2693 if (subtree.size() > 1)
2694 {
2695 // More then one PowerIdlePowerSaver object is not supported and
2696 // is an error
2697 BMCWEB_LOG_DEBUG(
2698 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2699 subtree.size());
2700 messages::internalError(asyncResp->res);
2701 return;
2702 }
2703 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2704 {
2705 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2706 messages::internalError(asyncResp->res);
2707 return;
2708 }
2709 const std::string& path = subtree[0].first;
2710 const std::string& service = subtree[0].second.begin()->first;
2711 if (service.empty())
2712 {
2713 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2714 messages::internalError(asyncResp->res);
2715 return;
2716 }
Chris Cain37bbf982021-09-20 10:53:09 -05002717
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002718 // Valid Power IdlePowerSaver object found, now set any values that
2719 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002720
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002721 if (ipsEnable)
2722 {
2723 setDbusProperty(
2724 asyncResp, "IdlePowerSaver/Enabled", service, path,
2725 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2726 "Enabled", *ipsEnable);
2727 }
2728 if (ipsEnterUtil)
2729 {
2730 setDbusProperty(
2731 asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2732 service, path,
2733 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2734 "EnterUtilizationPercent", *ipsEnterUtil);
2735 }
2736 if (ipsEnterTime)
2737 {
2738 // Convert from seconds into milliseconds for DBus
2739 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2740 setDbusProperty(
2741 asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2742 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2743 "EnterDwellTime", timeMilliseconds);
2744 }
2745 if (ipsExitUtil)
2746 {
2747 setDbusProperty(
2748 asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2749 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2750 "ExitUtilizationPercent", *ipsExitUtil);
2751 }
2752 if (ipsExitTime)
2753 {
2754 // Convert from seconds into milliseconds for DBus
2755 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2756 setDbusProperty(
2757 asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2758 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2759 "ExitDwellTime", timeMilliseconds);
2760 }
2761 });
Chris Cain37bbf982021-09-20 10:53:09 -05002762
Ed Tanous62598e32023-07-17 17:06:25 -07002763 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002764}
2765
Ed Tanousc1e219d2023-06-07 10:34:33 -07002766inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002767 crow::App& app, const crow::Request& req,
2768 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2769{
2770 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2771 {
2772 return;
2773 }
2774 asyncResp->res.addHeader(
2775 boost::beast::http::field::link,
2776 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2777}
2778
Ed Tanousc1e219d2023-06-07 10:34:33 -07002779inline void handleComputerSystemCollectionGet(
2780 crow::App& app, const crow::Request& req,
2781 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2782{
2783 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2784 {
2785 return;
2786 }
2787
2788 asyncResp->res.addHeader(
2789 boost::beast::http::field::link,
2790 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2791 asyncResp->res.jsonValue["@odata.type"] =
2792 "#ComputerSystemCollection.ComputerSystemCollection";
2793 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2794 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2795
2796 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2797 ifaceArray = nlohmann::json::array();
Ed Tanous25b54db2024-04-17 15:40:31 -07002798 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002799 {
2800 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2801 // Option currently returns no systems. TBD
2802 return;
2803 }
2804 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2805 nlohmann::json::object_t system;
Ed Tanous253f11b2024-05-16 09:38:31 -07002806 system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2807 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002808 ifaceArray.emplace_back(std::move(system));
Gunnar Mills68896202024-08-21 11:34:20 -05002809
2810 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2811 {
2812 BMCWEB_LOG_DEBUG("Hypervisor is available");
2813 asyncResp->res.jsonValue["Members@odata.count"] = 2;
2814
2815 nlohmann::json::object_t hypervisor;
2816 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2817 ifaceArray.emplace_back(std::move(hypervisor));
2818 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07002819}
2820
Yong Lic45f0082019-10-10 14:19:01 +08002821/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002822 * Function transceives data with dbus directly.
2823 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002824inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002825{
Patrick Williams89492a12023-05-10 07:51:34 -05002826 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2827 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2828 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002829 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002830 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002831
2832 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002833 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002834 if (ec)
2835 {
2836 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
2837 messages::internalError(asyncResp->res);
2838 return;
2839 }
2840 messages::success(asyncResp->res);
2841 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002842 serviceName, objectPath, interfaceName, method);
2843}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002844
Ed Tanousc1e219d2023-06-07 10:34:33 -07002845inline void handleComputerSystemResetActionPost(
2846 crow::App& app, const crow::Request& req,
2847 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2848 const std::string& systemName)
2849{
2850 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2851 {
2852 return;
2853 }
Gunnar Millsdd7090e2024-07-30 15:23:05 -05002854
2855 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2856 {
2857 if (systemName == "hypervisor")
2858 {
2859 handleHypervisorSystemResetPost(req, asyncResp);
2860 return;
2861 }
2862 }
2863
Ed Tanous253f11b2024-05-16 09:38:31 -07002864 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002865 {
2866 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2867 systemName);
2868 return;
2869 }
Ed Tanous25b54db2024-04-17 15:40:31 -07002870 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002871 {
2872 // Option currently returns no systems. TBD
2873 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2874 systemName);
2875 return;
2876 }
2877 std::string resetType;
2878 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2879 {
2880 return;
2881 }
2882
2883 // Get the command and host vs. chassis
2884 std::string command;
2885 bool hostCommand = true;
2886 if ((resetType == "On") || (resetType == "ForceOn"))
2887 {
2888 command = "xyz.openbmc_project.State.Host.Transition.On";
2889 hostCommand = true;
2890 }
2891 else if (resetType == "ForceOff")
2892 {
2893 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2894 hostCommand = false;
2895 }
2896 else if (resetType == "ForceRestart")
2897 {
2898 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2899 hostCommand = true;
2900 }
2901 else if (resetType == "GracefulShutdown")
2902 {
2903 command = "xyz.openbmc_project.State.Host.Transition.Off";
2904 hostCommand = true;
2905 }
2906 else if (resetType == "GracefulRestart")
2907 {
2908 command =
2909 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2910 hostCommand = true;
2911 }
2912 else if (resetType == "PowerCycle")
2913 {
2914 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2915 hostCommand = true;
2916 }
2917 else if (resetType == "Nmi")
2918 {
2919 doNMI(asyncResp);
2920 return;
2921 }
2922 else
2923 {
2924 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2925 return;
2926 }
Ed Tanousd02aad32024-02-13 14:43:34 -08002927 sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002928
2929 if (hostCommand)
2930 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302931 setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
Ed Tanousd02aad32024-02-13 14:43:34 -08002932 statePath / "host0", "xyz.openbmc_project.State.Host",
Ginu Georgee93abac2024-06-14 17:35:27 +05302933 "RequestedHostTransition", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002934 }
2935 else
2936 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302937 setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
Ed Tanousd02aad32024-02-13 14:43:34 -08002938 statePath / "chassis0",
2939 "xyz.openbmc_project.State.Chassis",
Ginu Georgee93abac2024-06-14 17:35:27 +05302940 "RequestedPowerTransition", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002941 }
2942}
2943
Ed Tanousc1e219d2023-06-07 10:34:33 -07002944inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002945 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002946 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2947 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002948{
2949 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2950 {
2951 return;
2952 }
2953
2954 asyncResp->res.addHeader(
2955 boost::beast::http::field::link,
2956 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2957}
2958
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002959inline void afterPortRequest(
2960 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2961 const boost::system::error_code& ec,
2962 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
2963{
2964 if (ec)
2965 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002966 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002967 messages::internalError(asyncResp->res);
2968 return;
2969 }
2970 for (const auto& data : socketData)
2971 {
2972 const std::string& socketPath = get<0>(data);
2973 const std::string& protocolName = get<1>(data);
2974 bool isProtocolEnabled = get<2>(data);
2975 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
2976 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
2977 // need to retrieve port number for
2978 // obmc-console-ssh service
2979 if (protocolName == "SSH")
2980 {
2981 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07002982 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002983 int portNumber) {
2984 if (ec1)
2985 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002986 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002987 messages::internalError(asyncResp->res);
2988 return;
2989 }
2990 nlohmann::json& dataJson1 =
2991 asyncResp->res.jsonValue["SerialConsole"];
2992 dataJson1[protocolName]["Port"] = portNumber;
2993 });
2994 }
2995 }
2996}
Ed Tanousc1e219d2023-06-07 10:34:33 -07002997
2998inline void
2999 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3000 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3001 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003002{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003003 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3004 {
3005 return;
3006 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003007
Ed Tanous25b54db2024-04-17 15:40:31 -07003008 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003009 {
3010 // Option currently returns no systems. TBD
3011 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3012 systemName);
3013 return;
3014 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003015
Gunnar Mills68896202024-08-21 11:34:20 -05003016 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003017 {
Gunnar Mills68896202024-08-21 11:34:20 -05003018 if (systemName == "hypervisor")
3019 {
3020 handleHypervisorSystemGet(asyncResp);
3021 return;
3022 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003023 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003024
Ed Tanous253f11b2024-05-16 09:38:31 -07003025 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003026 {
3027 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3028 systemName);
3029 return;
3030 }
3031 asyncResp->res.addHeader(
3032 boost::beast::http::field::link,
3033 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3034 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003035 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanous253f11b2024-05-16 09:38:31 -07003036 asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3037 asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
Ed Tanous539d8c62024-06-19 14:38:27 -07003038 asyncResp->res.jsonValue["SystemType"] =
3039 computer_system::SystemType::Physical;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003040 asyncResp->res.jsonValue["Description"] = "Computer System";
3041 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003042 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003043 double(0);
Ed Tanous253f11b2024-05-16 09:38:31 -07003044 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3045 "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous04a258f2018-10-15 08:00:41 -07003046
Ed Tanous253f11b2024-05-16 09:38:31 -07003047 asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3048 "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3049 asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3050 "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3051 asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3052 "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003053 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003054 boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3055 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous029573d2019-02-01 10:57:49 -08003056
Ed Tanousc1e219d2023-06-07 10:34:33 -07003057 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003058 boost::urls::format(
3059 "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3060 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003061 asyncResp->res
3062 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003063 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3064 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003065
Ed Tanous253f11b2024-05-16 09:38:31 -07003066 asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3067 "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3068 asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3069 "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003070
Ed Tanousc1e219d2023-06-07 10:34:33 -07003071 nlohmann::json::array_t managedBy;
3072 nlohmann::json& manager = managedBy.emplace_back();
Ed Tanous253f11b2024-05-16 09:38:31 -07003073 manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3074 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003075 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
Ed Tanous539d8c62024-06-19 14:38:27 -07003076 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3077 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003078
Ed Tanousc1e219d2023-06-07 10:34:33 -07003079 // Fill in SerialConsole info
3080 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3081 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003082
Ed Tanousc1e219d2023-06-07 10:34:33 -07003083 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3084 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3085 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3086 "Press ~. to exit console";
3087 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3088 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003089
Ed Tanous25b54db2024-04-17 15:40:31 -07003090 if constexpr (BMCWEB_KVM)
3091 {
3092 // Fill in GraphicalConsole info
3093 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3094 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3095 4;
3096 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3097 nlohmann::json::array_t({"KVMIP"});
3098 }
James Feistb49ac872019-05-21 15:12:01 -07003099
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003100 getMainChassisId(
3101 asyncResp, [](const std::string& chassisId,
3102 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3103 nlohmann::json::array_t chassisArray;
3104 nlohmann::json& chassis = chassisArray.emplace_back();
3105 chassis["@odata.id"] =
3106 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
3107 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3108 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003109
George Liu59a17e42022-10-08 09:27:47 +08003110 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003111 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3112 getIndicatorLedState(asyncResp);
Gunnar Mills51bd2d82024-04-01 15:25:51 -05003113 getComputerSystem(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003114 getHostState(asyncResp);
3115 getBootProperties(asyncResp);
3116 getBootProgress(asyncResp);
3117 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003118 pcie_util::getPCIeDeviceList(asyncResp,
3119 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003120 getHostWatchdogTimer(asyncResp);
3121 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003122 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003123 getAutomaticRetryPolicy(asyncResp);
3124 getLastResetTime(asyncResp);
Ed Tanous25b54db2024-04-17 15:40:31 -07003125 if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
3126 {
3127 getProvisioningStatus(asyncResp);
3128 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003129 getTrustedModuleRequiredToBoot(asyncResp);
3130 getPowerMode(asyncResp);
3131 getIdlePowerSaver(asyncResp);
3132}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003133
Ed Tanousc1e219d2023-06-07 10:34:33 -07003134inline void handleComputerSystemPatch(
3135 crow::App& app, const crow::Request& req,
3136 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3137 const std::string& systemName)
3138{
3139 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3140 {
3141 return;
3142 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003143 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003144 {
3145 // Option currently returns no systems. TBD
3146 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3147 systemName);
3148 return;
3149 }
Ed Tanous253f11b2024-05-16 09:38:31 -07003150 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003151 {
3152 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3153 systemName);
3154 return;
3155 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003156
Ed Tanousc1e219d2023-06-07 10:34:33 -07003157 asyncResp->res.addHeader(
3158 boost::beast::http::field::link,
3159 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003160
Ed Tanousc1e219d2023-06-07 10:34:33 -07003161 std::optional<bool> locationIndicatorActive;
3162 std::optional<std::string> indicatorLed;
3163 std::optional<std::string> assetTag;
3164 std::optional<std::string> powerRestorePolicy;
3165 std::optional<std::string> powerMode;
3166 std::optional<bool> wdtEnable;
3167 std::optional<std::string> wdtTimeOutAction;
3168 std::optional<std::string> bootSource;
3169 std::optional<std::string> bootType;
3170 std::optional<std::string> bootEnable;
3171 std::optional<std::string> bootAutomaticRetry;
3172 std::optional<uint32_t> bootAutomaticRetryAttempts;
3173 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003174 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003175 std::optional<bool> ipsEnable;
3176 std::optional<uint8_t> ipsEnterUtil;
3177 std::optional<uint64_t> ipsEnterTime;
3178 std::optional<uint8_t> ipsExitUtil;
3179 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003180
Myung Baeafc474a2024-10-09 00:53:29 -07003181 if (!json_util::readJsonPatch( //
3182 req, asyncResp->res, //
3183 "AssetTag", assetTag, //
3184 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, //
3185 "Boot/AutomaticRetryConfig", bootAutomaticRetry, //
3186 "Boot/BootSourceOverrideEnabled", bootEnable, //
3187 "Boot/BootSourceOverrideMode", bootType, //
3188 "Boot/BootSourceOverrideTarget", bootSource, //
3189 "Boot/StopBootOnFault", stopBootOnFault, //
3190 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, //
3191 "HostWatchdogTimer/FunctionEnabled", wdtEnable, //
3192 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, //
3193 "IdlePowerSaver/Enabled", ipsEnable, //
3194 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, //
3195 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, //
3196 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, //
3197 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, //
3198 "IndicatorLED", indicatorLed, //
3199 "LocationIndicatorActive", locationIndicatorActive, //
3200 "PowerMode", powerMode, //
3201 "PowerRestorePolicy", powerRestorePolicy //
3202 ))
Ed Tanousab344222024-08-07 18:01:23 -07003203 {
3204 return;
3205 }
James Feistb49ac872019-05-21 15:12:01 -07003206
Ed Tanousc1e219d2023-06-07 10:34:33 -07003207 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003208
Ed Tanousc1e219d2023-06-07 10:34:33 -07003209 if (assetTag)
3210 {
3211 setAssetTag(asyncResp, *assetTag);
3212 }
James Feistb49ac872019-05-21 15:12:01 -07003213
Ed Tanousc1e219d2023-06-07 10:34:33 -07003214 if (wdtEnable || wdtTimeOutAction)
3215 {
3216 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3217 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003218
Ed Tanousc1e219d2023-06-07 10:34:33 -07003219 if (bootSource || bootType || bootEnable)
3220 {
3221 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3222 }
3223 if (bootAutomaticRetry)
3224 {
3225 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3226 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003227
Ed Tanousc1e219d2023-06-07 10:34:33 -07003228 if (bootAutomaticRetryAttempts)
3229 {
3230 setAutomaticRetryAttempts(asyncResp,
3231 bootAutomaticRetryAttempts.value());
3232 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003233
Ed Tanousc1e219d2023-06-07 10:34:33 -07003234 if (bootTrustedModuleRequired)
3235 {
3236 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3237 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003238
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003239 if (stopBootOnFault)
3240 {
3241 setStopBootOnFault(asyncResp, *stopBootOnFault);
3242 }
3243
Ed Tanousc1e219d2023-06-07 10:34:33 -07003244 if (locationIndicatorActive)
3245 {
George Liu59a17e42022-10-08 09:27:47 +08003246 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003247 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003248
Ed Tanousc1e219d2023-06-07 10:34:33 -07003249 // TODO (Gunnar): Remove IndicatorLED after enough time has
3250 // passed
3251 if (indicatorLed)
3252 {
3253 setIndicatorLedState(asyncResp, *indicatorLed);
3254 asyncResp->res.addHeader(boost::beast::http::field::warning,
3255 "299 - \"IndicatorLED is deprecated. Use "
3256 "LocationIndicatorActive instead.\"");
3257 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003258
Ed Tanousc1e219d2023-06-07 10:34:33 -07003259 if (powerRestorePolicy)
3260 {
3261 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3262 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003263
Ed Tanousc1e219d2023-06-07 10:34:33 -07003264 if (powerMode)
3265 {
3266 setPowerMode(asyncResp, *powerMode);
3267 }
Chris Cain37bbf982021-09-20 10:53:09 -05003268
Ed Tanousc1e219d2023-06-07 10:34:33 -07003269 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3270 {
3271 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3272 ipsExitUtil, ipsExitTime);
3273 }
3274}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303275
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003276inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003277 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003278 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003279 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003280{
3281 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3282 {
3283 return;
3284 }
3285 asyncResp->res.addHeader(
3286 boost::beast::http::field::link,
3287 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3288}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003289
3290/**
3291 * @brief Translates allowed host transitions to redfish string
3292 *
3293 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3294 * @param[out] allowableValues The translated host transition(s)
3295 *
Manojkiran Edaefff2b52024-06-18 18:01:46 +05303296 * @return Emplaces corresponding Redfish translated value(s) in
Andrew Geissler33e1f122024-02-26 21:10:16 -06003297 * allowableValues. If translation not possible, does nothing to
3298 * allowableValues.
3299 */
3300inline void
3301 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3302 nlohmann::json::array_t& allowableValues)
3303{
3304 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3305 {
3306 allowableValues.emplace_back(resource::ResetType::On);
3307 allowableValues.emplace_back(resource::ResetType::ForceOn);
3308 }
3309 else if (dbusAllowedHostTran ==
3310 "xyz.openbmc_project.State.Host.Transition.Off")
3311 {
3312 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3313 }
3314 else if (dbusAllowedHostTran ==
3315 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3316 {
3317 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3318 }
3319 else if (dbusAllowedHostTran ==
3320 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3321 {
3322 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3323 }
3324 else
3325 {
3326 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3327 }
3328}
3329
3330inline void afterGetAllowedHostTransitions(
3331 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3332 const boost::system::error_code& ec,
3333 const std::vector<std::string>& allowedHostTransitions)
3334{
3335 nlohmann::json::array_t allowableValues;
3336
3337 // Supported on all systems currently
3338 allowableValues.emplace_back(resource::ResetType::ForceOff);
3339 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3340 allowableValues.emplace_back(resource::ResetType::Nmi);
3341
3342 if (ec)
3343 {
Ed Tanouse715d142024-03-07 15:47:37 -08003344 if ((ec.value() ==
3345 boost::system::linux_error::bad_request_descriptor) ||
3346 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003347 {
3348 // Property not implemented so just return defaults
3349 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3350 allowableValues.emplace_back(resource::ResetType::On);
3351 allowableValues.emplace_back(resource::ResetType::ForceOn);
3352 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3353 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3354 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3355 }
3356 else
3357 {
3358 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3359 messages::internalError(asyncResp->res);
3360 return;
3361 }
3362 }
3363 else
3364 {
3365 for (const std::string& transition : allowedHostTransitions)
3366 {
3367 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3368 dbusToRfAllowedHostTransitions(transition, allowableValues);
3369 }
3370 }
3371
3372 nlohmann::json::object_t parameter;
3373 parameter["Name"] = "ResetType";
3374 parameter["Required"] = true;
Ed Tanous539d8c62024-06-19 14:38:27 -07003375 parameter["DataType"] = action_info::ParameterTypes::String;
Andrew Geissler33e1f122024-02-26 21:10:16 -06003376 parameter["AllowableValues"] = std::move(allowableValues);
3377 nlohmann::json::array_t parameters;
3378 parameters.emplace_back(std::move(parameter));
3379 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3380}
3381
Ed Tanousc1e219d2023-06-07 10:34:33 -07003382inline void handleSystemCollectionResetActionGet(
3383 crow::App& app, const crow::Request& req,
3384 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3385 const std::string& systemName)
3386{
3387 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3388 {
3389 return;
3390 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003391 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003392 {
3393 // Option currently returns no systems. TBD
3394 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3395 systemName);
3396 return;
3397 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003398
Gunnar Mills68896202024-08-21 11:34:20 -05003399 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003400 {
Gunnar Mills68896202024-08-21 11:34:20 -05003401 if (systemName == "hypervisor")
3402 {
3403 handleHypervisorResetActionGet(asyncResp);
3404 return;
3405 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003406 }
3407
Ed Tanous253f11b2024-05-16 09:38:31 -07003408 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003409 {
3410 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3411 systemName);
3412 return;
3413 }
3414
3415 asyncResp->res.addHeader(
3416 boost::beast::http::field::link,
3417 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3418
3419 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003420 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3421 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003422 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3423 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3424 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3425
Andrew Geissler33e1f122024-02-26 21:10:16 -06003426 // Look to see if system defines AllowedHostTransitions
Ed Tanousdeae6a72024-11-11 21:58:57 -08003427 dbus::utility::getProperty<std::vector<std::string>>(
3428 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
3429 "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
Andrew Geissler33e1f122024-02-26 21:10:16 -06003430 [asyncResp](const boost::system::error_code& ec,
3431 const std::vector<std::string>& allowedHostTransitions) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003432 afterGetAllowedHostTransitions(asyncResp, ec,
3433 allowedHostTransitions);
3434 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003435}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303436/**
3437 * SystemResetActionInfo derived class for delivering Computer Systems
3438 * ResetType AllowableValues using ResetInfo schema.
3439 */
Ed Tanous100afe52023-06-07 13:30:46 -07003440inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303441{
Ed Tanous100afe52023-06-07 13:30:46 -07003442 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3443 .privileges(redfish::privileges::headComputerSystemCollection)
3444 .methods(boost::beast::http::verb::head)(
3445 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3446
3447 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3448 .privileges(redfish::privileges::getComputerSystemCollection)
3449 .methods(boost::beast::http::verb::get)(
3450 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3451
3452 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3453 .privileges(redfish::privileges::headComputerSystem)
3454 .methods(boost::beast::http::verb::head)(
3455 std::bind_front(handleComputerSystemHead, std::ref(app)));
3456
3457 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3458 .privileges(redfish::privileges::getComputerSystem)
3459 .methods(boost::beast::http::verb::get)(
3460 std::bind_front(handleComputerSystemGet, std::ref(app)));
3461
3462 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3463 .privileges(redfish::privileges::patchComputerSystem)
3464 .methods(boost::beast::http::verb::patch)(
3465 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3466
3467 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3468 .privileges(redfish::privileges::postComputerSystem)
3469 .methods(boost::beast::http::verb::post)(std::bind_front(
3470 handleComputerSystemResetActionPost, std::ref(app)));
3471
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003472 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003473 .privileges(redfish::privileges::headActionInfo)
3474 .methods(boost::beast::http::verb::head)(std::bind_front(
3475 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003476 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003477 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003478 .methods(boost::beast::http::verb::get)(std::bind_front(
3479 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003480}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003481} // namespace redfish