blob: 5265436e5b6bbd32c529bdcb3ac2368fbe6e9fb5 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020015*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070023#include "generated/enums/action_info.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070024#include "generated/enums/computer_system.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070025#include "generated/enums/open_bmc_computer_system.hpp"
Andrew Geissler33e1f122024-02-26 21:10:16 -060026#include "generated/enums/resource.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060027#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080028#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070029#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080030#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080031#include "registries/privilege_registry.hpp"
32#include "utils/dbus_utils.hpp"
33#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050034#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080035#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070036#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080037
Andrew Geisslerfc903b32023-05-31 14:15:42 -040038#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070039#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080040#include <boost/system/error_code.hpp>
Andrew Geissler33e1f122024-02-26 21:10:16 -060041#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070042#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070043#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040044#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020045#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050046
George Liu7a1dbc42022-12-07 16:03:22 +080047#include <array>
Andrew Geissler33e1f122024-02-26 21:10:16 -060048#include <memory>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060049#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080050#include <string_view>
Ed Tanous20fa6a22024-05-20 18:02:58 -070051#include <utility>
Ed Tanousabf2add2019-01-22 16:40:12 -080052#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060053#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020054
Ed Tanous1abe55e2018-09-05 08:30:59 -070055namespace redfish
56{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020057
Abhishek Patel5c3e9272021-06-24 10:11:33 -050058const static std::array<std::pair<std::string_view, std::string_view>, 2>
59 protocolToDBusForSystems{
60 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
61
Alpana Kumari9d3ae102019-04-12 06:49:32 -050062/**
63 * @brief Updates the Functional State of DIMMs
64 *
Ed Tanousac106bf2023-06-07 09:24:59 -070065 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050066 * @param[in] dimmState Dimm's Functional state, true/false
67 *
68 * @return None.
69 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -040070inline void updateDimmProperties(
71 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050072{
Ed Tanous62598e32023-07-17 17:06:25 -070073 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050074
Gunnar Mills4e0453b2020-07-08 14:00:30 -050075 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050076 // Update STATE only if previous State was DISABLED and current Dimm is
77 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070078 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070079 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050080 if (prevMemSummary == "Disabled")
81 {
Ed Tanouse05aec52022-01-25 10:28:56 -080082 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050083 {
Ed Tanousac106bf2023-06-07 09:24:59 -070084 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050085 "Enabled";
86 }
87 }
88}
89
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050090/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050091 * @brief Update "ProcessorSummary" "Status" "State" based on
92 * CPU Functional State
93 *
Ed Tanousac106bf2023-06-07 09:24:59 -070094 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050095 * @param[in] cpuFunctionalState is CPU functional true/false
96 *
97 * @return None.
98 */
Ed Tanousac106bf2023-06-07 09:24:59 -070099inline void modifyCpuFunctionalState(
100 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101{
Ed Tanous62598e32023-07-17 17:06:25 -0700102 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500103
Ed Tanous02cad962022-06-30 16:50:15 -0700104 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700105 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500106
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500107 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500108 // Update STATE only if previous State was Non_Functional and current CPU is
109 // Functional.
110 if (prevProcState == "Disabled")
111 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800112 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700114 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115 "Enabled";
116 }
117 }
118}
119
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500120/*
121 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
122 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700123 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500124 * @param[in] cpuPresenceState CPU present or not
125 *
126 * @return None.
127 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400128inline void modifyCpuPresenceState(
129 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500130{
Ed Tanous62598e32023-07-17 17:06:25 -0700131 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500132
133 if (isCpuPresent)
134 {
135 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700136 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500137 auto* procCountPtr =
138 procCount.get_ptr<nlohmann::json::number_integer_t*>();
139 if (procCountPtr != nullptr)
140 {
141 // shouldn't be possible to be nullptr
142 *procCountPtr += 1;
143 }
144 }
145}
146
Ali Ahmed382d6472021-09-03 16:53:53 -0500147inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500149 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500151{
Ed Tanous62598e32023-07-17 17:06:25 -0700152 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500153
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200154 // TODO: Get Model
155
156 const uint16_t* coreCount = nullptr;
157
158 const bool success = sdbusplus::unpackPropertiesNoThrow(
159 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
160
161 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500162 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700163 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200164 return;
165 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500166
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200167 if (coreCount != nullptr)
168 {
169 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700170 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200171 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500172
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200173 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500174 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200175 coreCountJson = *coreCount;
176 }
177 else
178 {
179 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500180 }
181 }
182}
183
184/*
185 * @brief Get ProcessorSummary fields
186 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500188 * @param[in] service dbus service for Cpu Information
189 * @param[in] path dbus path for Cpu
190 *
191 * @return None.
192 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700193inline void
194 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500196{
Ed Tanousac106bf2023-06-07 09:24:59 -0700197 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500199 if (ec3)
200 {
Ed Tanous62598e32023-07-17 17:06:25 -0700201 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500202 return;
203 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700204 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500205 };
206
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500207 // Get the Presence of CPU
208 sdbusplus::asio::getProperty<bool>(
209 *crow::connections::systemBus, service, path,
210 "xyz.openbmc_project.Inventory.Item", "Present",
211 std::move(getCpuPresenceState));
212
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200213 sdbusplus::asio::getAllProperties(
214 *crow::connections::systemBus, service, path,
215 "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700216 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800217 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800218 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400219 if (ec2)
220 {
221 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
222 messages::internalError(asyncResp->res);
223 return;
224 }
225 getProcessorProperties(asyncResp, properties);
226 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500227}
228
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500229/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500230 * @brief processMemoryProperties fields
231 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700232 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500233 * @param[in] DBUS properties for memory
234 *
235 * @return None.
236 */
237inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700238 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500239 const dbus::utility::DBusPropertiesMap& properties)
240{
Ed Tanous62598e32023-07-17 17:06:25 -0700241 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500242
243 if (properties.empty())
244 {
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500245 return;
246 }
247
248 const size_t* memorySizeInKB = nullptr;
249
250 const bool success = sdbusplus::unpackPropertiesNoThrow(
251 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
252 memorySizeInKB);
253
254 if (!success)
255 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700256 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500257 return;
258 }
259
260 if (memorySizeInKB != nullptr)
261 {
262 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700263 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500264 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500265 if (preValue == nullptr)
266 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700267 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500268 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500269 }
270 else
271 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700272 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500273 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
274 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500275 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500276 }
277}
278
279/*
280 * @brief Get getMemorySummary fields
281 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700282 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500283 * @param[in] service dbus service for memory Information
284 * @param[in] path dbus path for memory
285 *
286 * @return None.
287 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700288inline void
289 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
290 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500291{
292 sdbusplus::asio::getAllProperties(
293 *crow::connections::systemBus, service, path,
294 "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700295 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500296 path](const boost::system::error_code& ec2,
297 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400298 if (ec2)
299 {
300 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
301 messages::internalError(asyncResp->res);
302 return;
303 }
304 processMemoryProperties(asyncResp, properties);
305 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500306}
307
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500308inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
309 const boost::system::error_code& ec,
310 const dbus::utility::DBusPropertiesMap& properties)
311{
312 if (ec)
313 {
314 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
315 messages::internalError(asyncResp->res);
316 return;
317 }
318 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
319
320 const std::string* uUID = nullptr;
321
322 const bool success = sdbusplus::unpackPropertiesNoThrow(
323 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
324
325 if (!success)
326 {
327 messages::internalError(asyncResp->res);
328 return;
329 }
330
331 if (uUID != nullptr)
332 {
333 std::string valueStr = *uUID;
334 if (valueStr.size() == 32)
335 {
336 valueStr.insert(8, 1, '-');
337 valueStr.insert(13, 1, '-');
338 valueStr.insert(18, 1, '-');
339 valueStr.insert(23, 1, '-');
340 }
341 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
342 asyncResp->res.jsonValue["UUID"] = valueStr;
343 }
344}
345
346inline void
347 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
348 const boost::system::error_code& ec,
349 const dbus::utility::DBusPropertiesMap& propertiesList)
350{
351 if (ec)
352 {
353 // doesn't have to include this
354 // interface
355 return;
356 }
357 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
358
359 const std::string* partNumber = nullptr;
360 const std::string* serialNumber = nullptr;
361 const std::string* manufacturer = nullptr;
362 const std::string* model = nullptr;
363 const std::string* subModel = nullptr;
364
365 const bool success = sdbusplus::unpackPropertiesNoThrow(
366 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
367 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
368 "Model", model, "SubModel", subModel);
369
370 if (!success)
371 {
372 messages::internalError(asyncResp->res);
373 return;
374 }
375
376 if (partNumber != nullptr)
377 {
378 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
379 }
380
381 if (serialNumber != nullptr)
382 {
383 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
384 }
385
386 if (manufacturer != nullptr)
387 {
388 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
389 }
390
391 if (model != nullptr)
392 {
393 asyncResp->res.jsonValue["Model"] = *model;
394 }
395
396 if (subModel != nullptr)
397 {
398 asyncResp->res.jsonValue["SubModel"] = *subModel;
399 }
400
401 // Grab the bios version
402 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
403 "BiosVersion", false);
404}
405
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400406inline void afterGetAssetTag(
407 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
408 const boost::system::error_code& ec, const std::string& value)
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500409{
410 if (ec)
411 {
412 // doesn't have to include this
413 // interface
414 return;
415 }
416
417 asyncResp->res.jsonValue["AssetTag"] = value;
418}
419
420inline void afterSystemGetSubTree(
421 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500422 const boost::system::error_code& ec,
423 const dbus::utility::MapperGetSubTreeResponse& subtree)
424{
425 if (ec)
426 {
427 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
428 messages::internalError(asyncResp->res);
429 return;
430 }
431 // Iterate over all retrieved ObjectPaths.
432 for (const std::pair<
433 std::string,
434 std::vector<std::pair<std::string, std::vector<std::string>>>>&
435 object : subtree)
436 {
437 const std::string& path = object.first;
438 BMCWEB_LOG_DEBUG("Got path: {}", path);
439 const std::vector<std::pair<std::string, std::vector<std::string>>>&
440 connectionNames = object.second;
441 if (connectionNames.empty())
442 {
443 continue;
444 }
445
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500446 // This is not system, so check if it's cpu, dimm, UUID or
447 // BiosVer
448 for (const auto& connection : connectionNames)
449 {
450 for (const auto& interfaceName : connection.second)
451 {
452 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
453 {
454 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
455
456 getMemorySummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500457 }
458 else if (interfaceName ==
459 "xyz.openbmc_project.Inventory.Item.Cpu")
460 {
461 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
462
463 getProcessorSummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500464 }
465 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
466 {
467 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
468
469 sdbusplus::asio::getAllProperties(
470 *crow::connections::systemBus, connection.first, path,
471 "xyz.openbmc_project.Common.UUID",
472 [asyncResp](const boost::system::error_code& ec3,
473 const dbus::utility::DBusPropertiesMap&
474 properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400475 afterGetUUID(asyncResp, ec3, properties);
476 });
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500477 }
478 else if (interfaceName ==
479 "xyz.openbmc_project.Inventory.Item.System")
480 {
481 sdbusplus::asio::getAllProperties(
482 *crow::connections::systemBus, connection.first, path,
483 "xyz.openbmc_project.Inventory.Decorator.Asset",
484 [asyncResp](const boost::system::error_code& ec3,
485 const dbus::utility::DBusPropertiesMap&
486 properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400487 afterGetInventory(asyncResp, ec3, properties);
488 });
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500489
490 sdbusplus::asio::getProperty<std::string>(
491 *crow::connections::systemBus, connection.first, path,
492 "xyz.openbmc_project.Inventory.Decorator."
493 "AssetTag",
494 "AssetTag",
495 std::bind_front(afterGetAssetTag, asyncResp));
496 }
497 }
498 }
499 }
500}
501
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500502/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700503 * @brief Retrieves computer system properties over dbus
504 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700505 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ed Tanous6c34de42018-08-29 13:37:36 -0700506 *
507 * @return None.
508 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700509inline void
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500510 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700511{
Ed Tanous62598e32023-07-17 17:06:25 -0700512 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800513 constexpr std::array<std::string_view, 5> interfaces = {
514 "xyz.openbmc_project.Inventory.Decorator.Asset",
515 "xyz.openbmc_project.Inventory.Item.Cpu",
516 "xyz.openbmc_project.Inventory.Item.Dimm",
517 "xyz.openbmc_project.Inventory.Item.System",
518 "xyz.openbmc_project.Common.UUID",
519 };
520 dbus::utility::getSubTree(
521 "/xyz/openbmc_project/inventory", 0, interfaces,
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500522 std::bind_front(afterSystemGetSubTree, asyncResp));
Ed Tanous6c34de42018-08-29 13:37:36 -0700523}
524
525/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700526 * @brief Retrieves host state properties over dbus
527 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700528 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700529 *
530 * @return None.
531 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700532inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700533{
Ed Tanous62598e32023-07-17 17:06:25 -0700534 BMCWEB_LOG_DEBUG("Get host information.");
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700535 sdbusplus::asio::getProperty<std::string>(
536 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
537 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
538 "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700539 [asyncResp](const boost::system::error_code& ec,
540 const std::string& hostState) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400541 if (ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700542 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400543 if (ec == boost::system::errc::host_unreachable)
544 {
545 // Service not available, no error, just don't return
546 // host state info
547 BMCWEB_LOG_DEBUG("Service not available {}", ec);
548 return;
549 }
550 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
551 messages::internalError(asyncResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700552 return;
553 }
Ed Tanous66173382018-08-15 18:20:59 -0700554
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400555 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
556 // Verify Host State
557 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
558 {
559 asyncResp->res.jsonValue["PowerState"] =
560 resource::PowerState::On;
561 asyncResp->res.jsonValue["Status"]["State"] =
562 resource::State::Enabled;
563 }
564 else if (hostState ==
565 "xyz.openbmc_project.State.Host.HostState.Quiesced")
566 {
567 asyncResp->res.jsonValue["PowerState"] =
568 resource::PowerState::On;
569 asyncResp->res.jsonValue["Status"]["State"] =
570 resource::State::Quiesced;
571 }
572 else if (hostState ==
573 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
574 {
575 asyncResp->res.jsonValue["PowerState"] =
576 resource::PowerState::On;
577 asyncResp->res.jsonValue["Status"]["State"] =
578 resource::State::InTest;
579 }
580 else if (
581 hostState ==
582 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
583 {
584 asyncResp->res.jsonValue["PowerState"] =
585 resource::PowerState::PoweringOn;
586 asyncResp->res.jsonValue["Status"]["State"] =
587 resource::State::Starting;
588 }
589 else if (
590 hostState ==
591 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
592 {
593 asyncResp->res.jsonValue["PowerState"] =
594 resource::PowerState::PoweringOff;
595 asyncResp->res.jsonValue["Status"]["State"] =
596 resource::State::Disabled;
597 }
598 else
599 {
600 asyncResp->res.jsonValue["PowerState"] =
601 resource::PowerState::Off;
602 asyncResp->res.jsonValue["Status"]["State"] =
603 resource::State::Disabled;
604 }
605 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700606}
607
608/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500609 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530610 *
611 * @param[in] dbusSource The boot source in DBUS speak.
612 *
613 * @return Returns as a string, the boot source in Redfish terms. If translation
614 * cannot be done, returns an empty string.
615 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000616inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530617{
618 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
619 {
620 return "None";
621 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700622 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530623 {
624 return "Hdd";
625 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700626 if (dbusSource ==
627 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530628 {
629 return "Cd";
630 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700631 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530632 {
633 return "Pxe";
634 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700635 if (dbusSource ==
636 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700637 {
638 return "Usb";
639 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700640 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530641}
642
643/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300644 * @brief Translates boot type DBUS property value to redfish.
645 *
646 * @param[in] dbusType The boot type in DBUS speak.
647 *
648 * @return Returns as a string, the boot type in Redfish terms. If translation
649 * cannot be done, returns an empty string.
650 */
651inline std::string dbusToRfBootType(const std::string& dbusType)
652{
653 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
654 {
655 return "Legacy";
656 }
657 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
658 {
659 return "UEFI";
660 }
661 return "";
662}
663
664/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500665 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530666 *
667 * @param[in] dbusMode The boot mode in DBUS speak.
668 *
669 * @return Returns as a string, the boot mode in Redfish terms. If translation
670 * cannot be done, returns an empty string.
671 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000672inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530673{
674 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
675 {
676 return "None";
677 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700678 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530679 {
680 return "Diags";
681 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700682 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530683 {
684 return "BiosSetup";
685 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700686 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530687}
688
689/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600690 * @brief Translates boot progress DBUS property value to redfish.
691 *
692 * @param[in] dbusBootProgress The boot progress in DBUS speak.
693 *
694 * @return Returns as a string, the boot progress in Redfish terms. If
695 * translation cannot be done, returns "None".
696 */
697inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
698{
699 // Now convert the D-Bus BootProgress to the appropriate Redfish
700 // enum
701 std::string rfBpLastState = "None";
702 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
703 "ProgressStages.Unspecified")
704 {
705 rfBpLastState = "None";
706 }
707 else if (dbusBootProgress ==
708 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
709 "PrimaryProcInit")
710 {
711 rfBpLastState = "PrimaryProcessorInitializationStarted";
712 }
713 else if (dbusBootProgress ==
714 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715 "BusInit")
716 {
717 rfBpLastState = "BusInitializationStarted";
718 }
719 else if (dbusBootProgress ==
720 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721 "MemoryInit")
722 {
723 rfBpLastState = "MemoryInitializationStarted";
724 }
725 else if (dbusBootProgress ==
726 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727 "SecondaryProcInit")
728 {
729 rfBpLastState = "SecondaryProcessorInitializationStarted";
730 }
731 else if (dbusBootProgress ==
732 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733 "PCIInit")
734 {
735 rfBpLastState = "PCIResourceConfigStarted";
736 }
737 else if (dbusBootProgress ==
738 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739 "SystemSetup")
740 {
741 rfBpLastState = "SetupEntered";
742 }
743 else if (dbusBootProgress ==
744 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745 "SystemInitComplete")
746 {
747 rfBpLastState = "SystemHardwareInitializationComplete";
748 }
749 else if (dbusBootProgress ==
750 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
751 "OSStart")
752 {
753 rfBpLastState = "OSBootStarted";
754 }
755 else if (dbusBootProgress ==
756 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
757 "OSRunning")
758 {
759 rfBpLastState = "OSRunning";
760 }
761 else
762 {
Ed Tanous62598e32023-07-17 17:06:25 -0700763 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600764 // Just return the default
765 }
766 return rfBpLastState;
767}
768
769/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500770 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530771 *
772 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700773 * @param[out] bootSource The DBus source
774 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530775 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700776 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530777 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400778inline int assignBootParameters(
779 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
780 const std::string& rfSource, std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530781{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300782 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
783 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700784
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530785 if (rfSource == "None")
786 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700787 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530788 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700789 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530790 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700791 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
792 }
793 else if (rfSource == "Hdd")
794 {
795 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
796 }
797 else if (rfSource == "Diags")
798 {
799 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
800 }
801 else if (rfSource == "Cd")
802 {
803 bootSource =
804 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
805 }
806 else if (rfSource == "BiosSetup")
807 {
808 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530809 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700810 else if (rfSource == "Usb")
811 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700812 bootSource =
813 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700814 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530815 else
816 {
Ed Tanous62598e32023-07-17 17:06:25 -0700817 BMCWEB_LOG_DEBUG(
818 "Invalid property value for BootSourceOverrideTarget: {}",
819 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700820 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700821 "BootSourceTargetOverride");
822 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530823 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700824 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530825}
Ali Ahmed19817712021-06-29 17:01:52 -0500826
Andrew Geissler978b8802020-11-19 13:36:40 -0600827/**
828 * @brief Retrieves boot progress of the system
829 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700830 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600831 *
832 * @return None.
833 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700834inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600835{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700836 sdbusplus::asio::getProperty<std::string>(
837 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
838 "/xyz/openbmc_project/state/host0",
839 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700840 [asyncResp](const boost::system::error_code& ec,
841 const std::string& bootProgressStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400842 if (ec)
843 {
844 // BootProgress is an optional object so just do nothing if
845 // not found
846 return;
847 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600848
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400849 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600850
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400851 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
852 dbusToRfBootProgress(bootProgressStr);
853 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600854}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530855
856/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000857 * @brief Retrieves boot progress Last Update of the system
858 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700859 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000860 *
861 * @return None.
862 */
863inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700864 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000865{
866 sdbusplus::asio::getProperty<uint64_t>(
867 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
868 "/xyz/openbmc_project/state/host0",
869 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700870 [asyncResp](const boost::system::error_code& ec,
871 const uint64_t lastStateTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400872 if (ec)
873 {
874 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
875 return;
876 }
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000877
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400878 // BootProgressLastUpdate is the last time the BootProgress property
879 // was updated. The time is the Epoch time, number of microseconds
880 // since 1 Jan 1970 00::00::00 UTC."
881 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
882 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000883
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400884 // Convert to ISO 8601 standard
885 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
886 redfish::time_utils::getDateTimeUintUs(lastStateTime);
887 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000888}
889
890/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300891 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300892 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700893 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300894 *
895 * @return None.
896 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300897
Ed Tanousac106bf2023-06-07 09:24:59 -0700898inline void
899 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300900{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700901 sdbusplus::asio::getProperty<std::string>(
902 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
903 "/xyz/openbmc_project/control/host0/boot",
904 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700905 [asyncResp](const boost::system::error_code& ec,
906 const std::string& bootType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400907 if (ec)
908 {
909 // not an error, don't have to have the interface
910 return;
911 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300912
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400913 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300914
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400915 asyncResp->res
916 .jsonValue["Boot"]
917 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
918 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300919
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400920 auto rfType = dbusToRfBootType(bootType);
921 if (rfType.empty())
922 {
923 messages::internalError(asyncResp->res);
924 return;
925 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300926
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400927 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
928 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300929}
930
931/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300932 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530933 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700934 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530935 *
936 * @return None.
937 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300938
Ed Tanousac106bf2023-06-07 09:24:59 -0700939inline void
940 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530941{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700942 sdbusplus::asio::getProperty<std::string>(
943 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
944 "/xyz/openbmc_project/control/host0/boot",
945 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700946 [asyncResp](const boost::system::error_code& ec,
947 const std::string& bootModeStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400948 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530949 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400950 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
951 messages::internalError(asyncResp->res);
952 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530953 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400954
955 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
956
957 nlohmann::json::array_t allowed;
958 allowed.emplace_back("None");
959 allowed.emplace_back("Pxe");
960 allowed.emplace_back("Hdd");
961 allowed.emplace_back("Cd");
962 allowed.emplace_back("Diags");
963 allowed.emplace_back("BiosSetup");
964 allowed.emplace_back("Usb");
965
966 asyncResp->res
967 .jsonValue["Boot"]
968 ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
969 std::move(allowed);
970 if (bootModeStr !=
971 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
972 {
973 auto rfMode = dbusToRfBootMode(bootModeStr);
974 if (!rfMode.empty())
975 {
976 asyncResp->res
977 .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
978 }
979 }
980 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530981}
982
983/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300984 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530985 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700986 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530987 *
988 * @return None.
989 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300990
991inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700992 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530993{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700994 sdbusplus::asio::getProperty<std::string>(
995 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
996 "/xyz/openbmc_project/control/host0/boot",
997 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -0700998 [asyncResp](const boost::system::error_code& ec,
999 const std::string& bootSourceStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001000 if (ec)
Nan Zhou5ef735c2022-06-22 05:24:21 +00001001 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001002 if (ec.value() == boost::asio::error::host_unreachable)
1003 {
1004 return;
1005 }
1006 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1007 messages::internalError(asyncResp->res);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001008 return;
1009 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301010
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001011 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301012
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001013 auto rfSource = dbusToRfBootSource(bootSourceStr);
1014 if (!rfSource.empty())
1015 {
1016 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1017 rfSource;
1018 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001019
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001020 // Get BootMode as BootSourceOverrideTarget is constructed
1021 // from both BootSource and BootMode
1022 getBootOverrideMode(asyncResp);
1023 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024}
1025
1026/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001027 * @brief This functions abstracts all the logic behind getting a
1028 * "BootSourceOverrideEnabled" property from an overall boot override enable
1029 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001031 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301032 *
1033 * @return None.
1034 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301035
Ed Tanousac106bf2023-06-07 09:24:59 -07001036inline void processBootOverrideEnable(
1037 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1038 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001039{
1040 if (!bootOverrideEnableSetting)
1041 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001042 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1043 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001044 return;
1045 }
1046
1047 // If boot source override is enabled, we need to check 'one_time'
1048 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001049 sdbusplus::asio::getProperty<bool>(
1050 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1051 "/xyz/openbmc_project/control/host0/boot/one_time",
1052 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001053 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001054 if (ec)
1055 {
1056 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1057 messages::internalError(asyncResp->res);
1058 return;
1059 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301060
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001061 if (oneTimeSetting)
1062 {
1063 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1064 "Once";
1065 }
1066 else
1067 {
1068 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1069 "Continuous";
1070 }
1071 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301072}
1073
1074/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001075 * @brief Retrieves boot override enable over DBUS
1076 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001077 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001078 *
1079 * @return None.
1080 */
1081
1082inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001083 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001084{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001085 sdbusplus::asio::getProperty<bool>(
1086 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1087 "/xyz/openbmc_project/control/host0/boot",
1088 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001089 [asyncResp](const boost::system::error_code& ec,
1090 const bool bootOverrideEnable) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001091 if (ec)
Nan Zhou5ef735c2022-06-22 05:24:21 +00001092 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001093 if (ec.value() == boost::asio::error::host_unreachable)
1094 {
1095 return;
1096 }
1097 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1098 messages::internalError(asyncResp->res);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001099 return;
1100 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001101
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001102 processBootOverrideEnable(asyncResp, bootOverrideEnable);
1103 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001104}
1105
1106/**
1107 * @brief Retrieves boot source override properties
1108 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001109 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001110 *
1111 * @return None.
1112 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001113inline void
1114 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001115{
Ed Tanous62598e32023-07-17 17:06:25 -07001116 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001117
Ed Tanousac106bf2023-06-07 09:24:59 -07001118 getBootOverrideSource(asyncResp);
1119 getBootOverrideType(asyncResp);
1120 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001121}
1122
1123/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001124 * @brief Retrieves the Last Reset Time
1125 *
1126 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1127 * and power off. Even though this is the "system" Redfish object look at the
1128 * chassis D-Bus interface for the LastStateChangeTime since this has the
1129 * last power operation time.
1130 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001131 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001132 *
1133 * @return None.
1134 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001135inline void
1136 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001137{
Ed Tanous62598e32023-07-17 17:06:25 -07001138 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001139
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001140 sdbusplus::asio::getProperty<uint64_t>(
1141 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1142 "/xyz/openbmc_project/state/chassis0",
1143 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001144 [asyncResp](const boost::system::error_code& ec,
1145 uint64_t lastResetTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001146 if (ec)
1147 {
1148 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1149 return;
1150 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001151
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001152 // LastStateChangeTime is epoch time, in milliseconds
1153 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1154 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001155
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001156 // Convert to ISO 8601 standard
1157 asyncResp->res.jsonValue["LastResetTime"] =
1158 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
1159 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001160}
1161
1162/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001163 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1164 *
1165 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1166 * corresponding property "AttemptsLeft" that keeps track of the amount of
1167 * automatic retry attempts left are hosted in phosphor-state-manager through
1168 * dbus.
1169 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001170 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001171 *
1172 * @return None.
1173 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001174inline void getAutomaticRebootAttempts(
1175 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001176{
Ed Tanous62598e32023-07-17 17:06:25 -07001177 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001178
1179 sdbusplus::asio::getAllProperties(
1180 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1181 "/xyz/openbmc_project/state/host0",
1182 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001183 [asyncResp{asyncResp}](
1184 const boost::system::error_code& ec,
1185 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001186 if (ec)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001187 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001188 if (ec.value() != EBADR)
1189 {
1190 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1191 messages::internalError(asyncResp->res);
1192 }
1193 return;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001194 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001195
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001196 const uint32_t* attemptsLeft = nullptr;
1197 const uint32_t* retryAttempts = nullptr;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001198
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001199 const bool success = sdbusplus::unpackPropertiesNoThrow(
1200 dbus_utils::UnpackErrorPrinter(), propertiesList,
1201 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001202
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001203 if (!success)
1204 {
1205 messages::internalError(asyncResp->res);
1206 return;
1207 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001208
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001209 if (attemptsLeft != nullptr)
1210 {
1211 asyncResp->res
1212 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1213 *attemptsLeft;
1214 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001215
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001216 if (retryAttempts != nullptr)
1217 {
1218 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1219 *retryAttempts;
1220 }
1221 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001222}
1223
1224/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001225 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1226 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001227 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001228 *
1229 * @return None.
1230 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001231inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001232 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001233{
Ed Tanous62598e32023-07-17 17:06:25 -07001234 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001235
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001236 sdbusplus::asio::getProperty<bool>(
1237 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1238 "/xyz/openbmc_project/control/host0/auto_reboot",
1239 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001240 [asyncResp](const boost::system::error_code& ec,
1241 bool autoRebootEnabled) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001242 if (ec)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001243 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001244 if (ec.value() != EBADR)
1245 {
1246 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1247 messages::internalError(asyncResp->res);
1248 }
1249 return;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001250 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001251
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001252 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1253 if (autoRebootEnabled)
1254 {
1255 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1256 "RetryAttempts";
1257 }
1258 else
1259 {
1260 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1261 "Disabled";
1262 }
1263 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001264
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001265 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1266 // and RetryAttempts. OpenBMC only supports Disabled and
1267 // RetryAttempts.
1268 nlohmann::json::array_t allowed;
1269 allowed.emplace_back("Disabled");
1270 allowed.emplace_back("RetryAttempts");
1271 asyncResp->res
1272 .jsonValue["Boot"]
1273 ["AutomaticRetryConfig@Redfish.AllowableValues"] =
1274 std::move(allowed);
1275 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001276}
1277
1278/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001279 * @brief Sets RetryAttempts
1280 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001281 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001282 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1283 *
1284 *@return None.
1285 */
1286
Ed Tanousac106bf2023-06-07 09:24:59 -07001287inline void setAutomaticRetryAttempts(
1288 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1289 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001290{
Ed Tanous62598e32023-07-17 17:06:25 -07001291 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001292 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301293 asyncResp, "Boot/AutomaticRetryAttempts",
1294 "xyz.openbmc_project.State.Host",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001295 sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
Corey Hardesty797d5da2022-04-26 17:54:52 +08001296 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
Ginu Georgee93abac2024-06-14 17:35:27 +05301297 retryAttempts);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001298}
1299
Ed Tanous8d69c662023-06-21 10:29:06 -07001300inline computer_system::PowerRestorePolicyTypes
1301 redfishPowerRestorePolicyFromDbus(std::string_view value)
1302{
1303 if (value ==
1304 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1305 {
1306 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1307 }
1308 if (value ==
1309 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1310 {
1311 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1312 }
1313 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001314 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001315 {
1316 return computer_system::PowerRestorePolicyTypes::LastState;
1317 }
1318 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1319 {
1320 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1321 }
1322 return computer_system::PowerRestorePolicyTypes::Invalid;
1323}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001324/**
George Liuc6a620f2020-04-10 17:18:11 +08001325 * @brief Retrieves power restore policy over DBUS.
1326 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001327 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001328 *
1329 * @return None.
1330 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001331inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001332 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001333{
Ed Tanous62598e32023-07-17 17:06:25 -07001334 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001335
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001336 sdbusplus::asio::getProperty<std::string>(
1337 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1338 "/xyz/openbmc_project/control/host0/power_restore_policy",
1339 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001340 [asyncResp](const boost::system::error_code& ec,
1341 const std::string& policy) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001342 if (ec)
1343 {
1344 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1345 return;
1346 }
1347 computer_system::PowerRestorePolicyTypes restore =
1348 redfishPowerRestorePolicyFromDbus(policy);
1349 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1350 {
1351 messages::internalError(asyncResp->res);
1352 return;
1353 }
George Liuc6a620f2020-04-10 17:18:11 +08001354
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001355 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
1356 });
George Liuc6a620f2020-04-10 17:18:11 +08001357}
1358
1359/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001360 * @brief Stop Boot On Fault over DBUS.
1361 *
1362 * @param[in] asyncResp Shared pointer for generating response message.
1363 *
1364 * @return None.
1365 */
1366inline void
1367 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1368{
Ed Tanous62598e32023-07-17 17:06:25 -07001369 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001370
1371 sdbusplus::asio::getProperty<bool>(
1372 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1373 "/xyz/openbmc_project/logging/settings",
1374 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1375 [asyncResp](const boost::system::error_code& ec, bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001376 if (ec)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001377 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001378 if (ec.value() != EBADR)
1379 {
1380 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1381 messages::internalError(asyncResp->res);
1382 }
1383 return;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001384 }
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001385
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001386 if (value)
1387 {
1388 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1389 computer_system::StopBootOnFault::AnyFault;
1390 }
1391 else
1392 {
1393 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1394 computer_system::StopBootOnFault::Never;
1395 }
1396 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001397}
1398
1399/**
Ali Ahmed19817712021-06-29 17:01:52 -05001400 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1401 * TPM is required for booting the host.
1402 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001403 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001404 *
1405 * @return None.
1406 */
1407inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001408 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001409{
Ed Tanous62598e32023-07-17 17:06:25 -07001410 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001411 constexpr std::array<std::string_view, 1> interfaces = {
1412 "xyz.openbmc_project.Control.TPM.Policy"};
1413 dbus::utility::getSubTree(
1414 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001415 [asyncResp](const boost::system::error_code& ec,
1416 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001417 if (ec)
Ali Ahmed19817712021-06-29 17:01:52 -05001418 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001419 BMCWEB_LOG_DEBUG(
1420 "DBUS response error on TPM.Policy GetSubTree{}", ec);
1421 // This is an optional D-Bus object so just return if
1422 // error occurs
1423 return;
1424 }
1425 if (subtree.empty())
1426 {
1427 // As noted above, this is an optional interface so just return
1428 // if there is no instance found
1429 return;
1430 }
1431
1432 /* When there is more than one TPMEnable object... */
1433 if (subtree.size() > 1)
1434 {
1435 BMCWEB_LOG_DEBUG(
1436 "DBUS response has more than 1 TPM Enable object:{}",
1437 subtree.size());
1438 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001439 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001440 return;
1441 }
1442
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001443 // Make sure the Dbus response map has a service and objectPath
1444 // field
1445 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
Ali Ahmed19817712021-06-29 17:01:52 -05001446 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001447 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1448 messages::internalError(asyncResp->res);
1449 return;
Ali Ahmed19817712021-06-29 17:01:52 -05001450 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001451
1452 const std::string& path = subtree[0].first;
1453 const std::string& serv = subtree[0].second.begin()->first;
1454
1455 // Valid TPM Enable object found, now reading the current value
1456 sdbusplus::asio::getProperty<bool>(
1457 *crow::connections::systemBus, serv, path,
1458 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1459 [asyncResp](const boost::system::error_code& ec2,
1460 bool tpmRequired) {
1461 if (ec2)
1462 {
1463 BMCWEB_LOG_ERROR(
1464 "D-BUS response error on TPM.Policy Get{}", ec2);
1465 messages::internalError(asyncResp->res);
1466 return;
1467 }
1468
1469 if (tpmRequired)
1470 {
1471 asyncResp->res
1472 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1473 "Required";
1474 }
1475 else
1476 {
1477 asyncResp->res
1478 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1479 "Disabled";
1480 }
1481 });
George Liue99073f2022-12-09 11:06:16 +08001482 });
Ali Ahmed19817712021-06-29 17:01:52 -05001483}
1484
1485/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001486 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1487 * TPM is required for booting the host.
1488 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001489 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001490 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1491 *
1492 * @return None.
1493 */
1494inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001495 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001496{
Ed Tanous62598e32023-07-17 17:06:25 -07001497 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001498 constexpr std::array<std::string_view, 1> interfaces = {
1499 "xyz.openbmc_project.Control.TPM.Policy"};
1500 dbus::utility::getSubTree(
1501 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001502 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001503 tpmRequired](const boost::system::error_code& ec,
1504 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001505 if (ec)
1506 {
1507 BMCWEB_LOG_ERROR(
1508 "DBUS response error on TPM.Policy GetSubTree{}", ec);
1509 messages::internalError(asyncResp->res);
1510 return;
1511 }
1512 if (subtree.empty())
1513 {
1514 messages::propertyValueNotInList(asyncResp->res,
1515 "ComputerSystem",
1516 "TrustedModuleRequiredToBoot");
1517 return;
1518 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001519
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001520 /* When there is more than one TPMEnable object... */
1521 if (subtree.size() > 1)
1522 {
1523 BMCWEB_LOG_DEBUG(
1524 "DBUS response has more than 1 TPM Enable object:{}",
1525 subtree.size());
1526 // Throw an internal Error and return
1527 messages::internalError(asyncResp->res);
1528 return;
1529 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001530
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001531 // Make sure the Dbus response map has a service and objectPath
1532 // field
1533 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1534 {
1535 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1536 messages::internalError(asyncResp->res);
1537 return;
1538 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001539
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001540 const std::string& path = subtree[0].first;
1541 const std::string& serv = subtree[0].second.begin()->first;
Ed Tanous002d39b2022-05-31 08:59:27 -07001542
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001543 if (serv.empty())
1544 {
1545 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1546 messages::internalError(asyncResp->res);
1547 return;
1548 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001549
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001550 // Valid TPM Enable object found, now setting the value
1551 setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1552 path, "xyz.openbmc_project.Control.TPM.Policy",
1553 "TPMEnable", tpmRequired);
1554 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001555}
1556
1557/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301558 * @brief Sets boot properties into DBUS object(s).
1559 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001560 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001561 * @param[in] bootType The boot type to set.
1562 * @return Integer error code.
1563 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001564inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001565 const std::optional<std::string>& bootType)
1566{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001567 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001568
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001569 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001570 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001571 return;
1572 }
1573
1574 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001575 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001576 // Figure out which DBUS interface and property to use
1577 if (*bootType == "Legacy")
1578 {
1579 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1580 }
1581 else if (*bootType == "UEFI")
1582 {
1583 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1584 }
1585 else
1586 {
Ed Tanous62598e32023-07-17 17:06:25 -07001587 BMCWEB_LOG_DEBUG("Invalid property value for "
1588 "BootSourceOverrideMode: {}",
1589 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001590 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001591 "BootSourceOverrideMode");
1592 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001593 }
1594
1595 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001596 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001597
Ginu Georgee93abac2024-06-14 17:35:27 +05301598 setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1599 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001600 sdbusplus::message::object_path(
1601 "/xyz/openbmc_project/control/host0/boot"),
1602 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ginu Georgee93abac2024-06-14 17:35:27 +05301603 bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001604}
1605
1606/**
1607 * @brief Sets boot properties into DBUS object(s).
1608 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001609 * @param[in] asyncResp Shared pointer for generating response
1610 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001611 * @param[in] bootType The boot type to set.
1612 * @return Integer error code.
1613 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001614inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001615 const std::optional<std::string>& bootEnable)
1616{
1617 if (!bootEnable)
1618 {
1619 return;
1620 }
1621 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001622 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001623
1624 bool bootOverrideEnable = false;
1625 bool bootOverridePersistent = false;
1626 // Figure out which DBUS interface and property to use
1627 if (*bootEnable == "Disabled")
1628 {
1629 bootOverrideEnable = false;
1630 }
1631 else if (*bootEnable == "Once")
1632 {
1633 bootOverrideEnable = true;
1634 bootOverridePersistent = false;
1635 }
1636 else if (*bootEnable == "Continuous")
1637 {
1638 bootOverrideEnable = true;
1639 bootOverridePersistent = true;
1640 }
1641 else
1642 {
Ed Tanous62598e32023-07-17 17:06:25 -07001643 BMCWEB_LOG_DEBUG(
1644 "Invalid property value for BootSourceOverrideEnabled: {}",
1645 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001646 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001647 "BootSourceOverrideEnabled");
1648 return;
1649 }
1650
1651 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001652 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001653
Ginu Georgee93abac2024-06-14 17:35:27 +05301654 setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1655 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001656 sdbusplus::message::object_path(
1657 "/xyz/openbmc_project/control/host0/boot"),
1658 "xyz.openbmc_project.Object.Enable", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05301659 bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001660
1661 if (!bootOverrideEnable)
1662 {
1663 return;
1664 }
1665
1666 // In case boot override is enabled we need to set correct value for the
1667 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001668 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1669 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001670
Ginu Georgee93abac2024-06-14 17:35:27 +05301671 setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1672 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001673 sdbusplus::message::object_path(
1674 "/xyz/openbmc_project/control/host0/boot/one_time"),
1675 "xyz.openbmc_project.Object.Enable", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05301676 !bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001677}
1678
1679/**
1680 * @brief Sets boot properties into DBUS object(s).
1681 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001682 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301683 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301684 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001685 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301686 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001687inline void
1688 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1689 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301690{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001691 std::string bootSourceStr;
1692 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001693
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001694 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301695 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001696 return;
1697 }
1698
1699 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001700 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001701 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001702 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1703 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001704 {
Ed Tanous62598e32023-07-17 17:06:25 -07001705 BMCWEB_LOG_DEBUG(
1706 "Invalid property value for BootSourceOverrideTarget: {}",
1707 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001708 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001709 "BootSourceTargetOverride");
1710 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001711 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301712
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001713 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001714 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1715 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001716
Ginu Georgee93abac2024-06-14 17:35:27 +05301717 setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1718 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001719 sdbusplus::message::object_path(
1720 "/xyz/openbmc_project/control/host0/boot"),
1721 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ginu Georgee93abac2024-06-14 17:35:27 +05301722 bootSourceStr);
1723 setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1724 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001725 sdbusplus::message::object_path(
1726 "/xyz/openbmc_project/control/host0/boot"),
1727 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ginu Georgee93abac2024-06-14 17:35:27 +05301728 bootModeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001729}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001730
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001731/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001732 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301733 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001734 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301735 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001736 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301737 * @param[in] bootEnable The boot override enable from incoming RF request.
1738 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001739 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301740 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001741
Ed Tanousac106bf2023-06-07 09:24:59 -07001742inline void
1743 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1744 const std::optional<std::string>& bootSource,
1745 const std::optional<std::string>& bootType,
1746 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301747{
Ed Tanous62598e32023-07-17 17:06:25 -07001748 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301749
Ed Tanousac106bf2023-06-07 09:24:59 -07001750 setBootModeOrSource(asyncResp, bootSource);
1751 setBootType(asyncResp, bootType);
1752 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301753}
1754
George Liuc6a620f2020-04-10 17:18:11 +08001755/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001756 * @brief Sets AssetTag
1757 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001758 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001759 * @param[in] assetTag "AssetTag" from request.
1760 *
1761 * @return None.
1762 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001763inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001764 const std::string& assetTag)
1765{
George Liue99073f2022-12-09 11:06:16 +08001766 constexpr std::array<std::string_view, 1> interfaces = {
1767 "xyz.openbmc_project.Inventory.Item.System"};
1768 dbus::utility::getSubTree(
1769 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001770 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001771 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001772 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001773 if (ec)
1774 {
1775 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1776 messages::internalError(asyncResp->res);
1777 return;
1778 }
1779 if (subtree.empty())
1780 {
1781 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1782 messages::internalError(asyncResp->res);
1783 return;
1784 }
1785 // Assume only 1 system D-Bus object
1786 // Throw an error if there is more than 1
1787 if (subtree.size() > 1)
1788 {
1789 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1790 messages::internalError(asyncResp->res);
1791 return;
1792 }
1793 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1794 {
1795 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1796 messages::internalError(asyncResp->res);
1797 return;
1798 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001799
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001800 const std::string& path = subtree[0].first;
1801 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001802
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001803 if (service.empty())
1804 {
1805 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1806 messages::internalError(asyncResp->res);
1807 return;
1808 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001809
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001810 setDbusProperty(asyncResp, "AssetTag", service, path,
1811 "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1812 "AssetTag", assetTag);
1813 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001814}
1815
1816/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001817 * @brief Validate the specified stopBootOnFault is valid and return the
1818 * stopBootOnFault name associated with that string
1819 *
1820 * @param[in] stopBootOnFaultString String representing the desired
1821 * stopBootOnFault
1822 *
1823 * @return stopBootOnFault value or empty if incoming value is not valid
1824 */
1825inline std::optional<bool>
1826 validstopBootOnFault(const std::string& stopBootOnFaultString)
1827{
1828 if (stopBootOnFaultString == "AnyFault")
1829 {
1830 return true;
1831 }
1832
1833 if (stopBootOnFaultString == "Never")
1834 {
1835 return false;
1836 }
1837
1838 return std::nullopt;
1839}
1840
1841/**
1842 * @brief Sets stopBootOnFault
1843 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001844 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001845 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1846 *
1847 * @return None.
1848 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001849inline void
1850 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1851 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001852{
Ed Tanous62598e32023-07-17 17:06:25 -07001853 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001854
1855 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1856 if (!stopBootEnabled)
1857 {
Ed Tanous62598e32023-07-17 17:06:25 -07001858 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1859 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001860 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001861 "StopBootOnFault");
1862 return;
1863 }
1864
Ginu Georgee93abac2024-06-14 17:35:27 +05301865 setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1866 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001867 sdbusplus::message::object_path(
1868 "/xyz/openbmc_project/logging/settings"),
1869 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
Ginu Georgee93abac2024-06-14 17:35:27 +05301870 *stopBootEnabled);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001871}
1872
1873/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001874 * @brief Sets automaticRetry (Auto Reboot)
1875 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001876 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001877 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1878 *
1879 * @return None.
1880 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001881inline void
1882 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1883 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001884{
Ed Tanous62598e32023-07-17 17:06:25 -07001885 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001886
1887 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001888 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001889
1890 if (automaticRetryConfig == "Disabled")
1891 {
1892 autoRebootEnabled = false;
1893 }
1894 else if (automaticRetryConfig == "RetryAttempts")
1895 {
1896 autoRebootEnabled = true;
1897 }
1898 else
1899 {
Ed Tanous62598e32023-07-17 17:06:25 -07001900 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
1901 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07001902 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001903 "AutomaticRetryConfig");
1904 return;
1905 }
1906
Ginu Georgee93abac2024-06-14 17:35:27 +05301907 setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1908 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001909 sdbusplus::message::object_path(
1910 "/xyz/openbmc_project/control/host0/auto_reboot"),
1911 "xyz.openbmc_project.Control.Boot.RebootPolicy",
Ginu Georgee93abac2024-06-14 17:35:27 +05301912 "AutoReboot", autoRebootEnabled);
Gunnar Mills69f35302020-05-17 16:06:31 -05001913}
1914
Ed Tanous8d69c662023-06-21 10:29:06 -07001915inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1916{
1917 if (policy == "AlwaysOn")
1918 {
1919 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1920 }
1921 if (policy == "AlwaysOff")
1922 {
1923 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1924 }
1925 if (policy == "LastState")
1926 {
1927 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1928 }
1929 return "";
1930}
1931
Gunnar Mills69f35302020-05-17 16:06:31 -05001932/**
George Liuc6a620f2020-04-10 17:18:11 +08001933 * @brief Sets power restore policy properties.
1934 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001935 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001936 * @param[in] policy power restore policy properties from request.
1937 *
1938 * @return None.
1939 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001940inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001941 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001942 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08001943{
Ed Tanous62598e32023-07-17 17:06:25 -07001944 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08001945
Ed Tanous8d69c662023-06-21 10:29:06 -07001946 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001947
Ed Tanous8d69c662023-06-21 10:29:06 -07001948 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08001949 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001950 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06001951 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001952 return;
1953 }
1954
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001955 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301956 asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001957 sdbusplus::message::object_path(
1958 "/xyz/openbmc_project/control/host0/power_restore_policy"),
George Liuc6a620f2020-04-10 17:18:11 +08001959 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ginu Georgee93abac2024-06-14 17:35:27 +05301960 powerRestorePolicy);
George Liuc6a620f2020-04-10 17:18:11 +08001961}
1962
AppaRao Pulia6349912019-10-18 17:16:08 +05301963/**
1964 * @brief Retrieves provisioning status
1965 *
Ed Tanous25b54db2024-04-17 15:40:31 -07001966 * @param[in] asyncResp Shared pointer for completing asynchronous
1967 * calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05301968 *
1969 * @return None.
1970 */
Ed Tanous25b54db2024-04-17 15:40:31 -07001971inline void
1972 getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301973{
Ed Tanous62598e32023-07-17 17:06:25 -07001974 BMCWEB_LOG_DEBUG("Get OEM information.");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001975 sdbusplus::asio::getAllProperties(
1976 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1977 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07001978 [asyncResp](const boost::system::error_code& ec,
1979 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001980 nlohmann::json& oemPFR =
1981 asyncResp->res
1982 .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1983 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1984 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1985 oemPFR["@odata.type"] =
1986 "#OpenBMCComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07001987
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001988 if (ec)
AppaRao Pulia6349912019-10-18 17:16:08 +05301989 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001990 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1991 // not an error, don't have to have the interface
Ed Tanous539d8c62024-06-19 14:38:27 -07001992 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001993 FirmwareProvisioningStatus::NotProvisioned;
1994 return;
1995 }
1996
1997 const bool* provState = nullptr;
1998 const bool* lockState = nullptr;
1999
2000 const bool success = sdbusplus::unpackPropertiesNoThrow(
2001 dbus_utils::UnpackErrorPrinter(), propertiesList,
2002 "UfmProvisioned", provState, "UfmLocked", lockState);
2003
2004 if (!success)
2005 {
2006 messages::internalError(asyncResp->res);
2007 return;
2008 }
2009
2010 if ((provState == nullptr) || (lockState == nullptr))
2011 {
2012 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2013 messages::internalError(asyncResp->res);
2014 return;
2015 }
2016
2017 if (*provState)
2018 {
2019 if (*lockState)
2020 {
2021 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2022 FirmwareProvisioningStatus::ProvisionedAndLocked;
2023 }
2024 else
2025 {
2026 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2027 FirmwareProvisioningStatus::ProvisionedButNotLocked;
2028 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302029 }
2030 else
2031 {
Ed Tanous539d8c62024-06-19 14:38:27 -07002032 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002033 FirmwareProvisioningStatus::NotProvisioned;
AppaRao Pulia6349912019-10-18 17:16:08 +05302034 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002035 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302036}
AppaRao Pulia6349912019-10-18 17:16:08 +05302037
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302038/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002039 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002040 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002041 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002042 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002043 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002044 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002045inline computer_system::PowerMode
2046 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002047{
Chris Cainb6655102024-02-01 14:35:33 -06002048 using PowerMode = computer_system::PowerMode;
2049
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002050 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002051 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002052 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002053 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002054 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002055 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002056 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002057 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002058 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002059 if (modeString ==
2060 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002061 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002062 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002063 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002064 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002065 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2066 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002067 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002068 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002069 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002070 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2071 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002072 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002073 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002074 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002075 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2076 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002077 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002078 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002079 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002080 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002081 return PowerMode::OEM;
2082 }
2083 // Any other values would be invalid
2084 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2085 return PowerMode::Invalid;
2086}
2087
2088inline void
2089 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2090 const boost::system::error_code& ec,
2091 const dbus::utility::DBusPropertiesMap& properties)
2092{
2093 if (ec)
2094 {
2095 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2096 messages::internalError(asyncResp->res);
2097 return;
2098 }
2099
2100 std::string powerMode;
2101 const std::vector<std::string>* allowedModes = nullptr;
2102 const bool success = sdbusplus::unpackPropertiesNoThrow(
2103 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2104 "AllowedPowerModes", allowedModes);
2105
2106 if (!success)
2107 {
2108 messages::internalError(asyncResp->res);
2109 return;
2110 }
2111
2112 nlohmann::json::array_t modeList;
2113 if (allowedModes == nullptr)
2114 {
2115 modeList.emplace_back("Static");
2116 modeList.emplace_back("MaximumPerformance");
2117 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002118 }
2119 else
2120 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002121 for (const auto& aMode : *allowedModes)
2122 {
2123 computer_system::PowerMode modeValue =
2124 translatePowerModeString(aMode);
2125 if (modeValue == computer_system::PowerMode::Invalid)
2126 {
2127 messages::internalError(asyncResp->res);
2128 continue;
2129 }
2130 modeList.emplace_back(modeValue);
2131 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002132 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002133 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002134
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002135 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2136 const computer_system::PowerMode modeValue =
2137 translatePowerModeString(powerMode);
2138 if (modeValue == computer_system::PowerMode::Invalid)
2139 {
2140 messages::internalError(asyncResp->res);
2141 return;
2142 }
2143 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2144}
Chris Cain3a2d04242021-05-28 16:57:10 -05002145/**
2146 * @brief Retrieves system power mode
2147 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002148 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002149 *
2150 * @return None.
2151 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002152inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002153{
Ed Tanous62598e32023-07-17 17:06:25 -07002154 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002155
2156 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002157 constexpr std::array<std::string_view, 1> interfaces = {
2158 "xyz.openbmc_project.Control.Power.Mode"};
2159 dbus::utility::getSubTree(
2160 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002161 [asyncResp](const boost::system::error_code& ec,
2162 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002163 if (ec)
2164 {
2165 BMCWEB_LOG_DEBUG(
2166 "DBUS response error on Power.Mode GetSubTree {}", ec);
2167 // This is an optional D-Bus object so just return if
2168 // error occurs
2169 return;
2170 }
2171 if (subtree.empty())
2172 {
2173 // As noted above, this is an optional interface so just return
2174 // if there is no instance found
2175 return;
2176 }
2177 if (subtree.size() > 1)
2178 {
2179 // More then one PowerMode object is not supported and is an
2180 // error
2181 BMCWEB_LOG_DEBUG(
2182 "Found more than 1 system D-Bus Power.Mode objects: {}",
2183 subtree.size());
2184 messages::internalError(asyncResp->res);
2185 return;
2186 }
2187 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2188 {
2189 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2190 messages::internalError(asyncResp->res);
2191 return;
2192 }
2193 const std::string& path = subtree[0].first;
2194 const std::string& service = subtree[0].second.begin()->first;
2195 if (service.empty())
2196 {
2197 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2198 messages::internalError(asyncResp->res);
2199 return;
2200 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002201
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002202 // Valid Power Mode object found, now read the mode properties
2203 sdbusplus::asio::getAllProperties(
2204 *crow::connections::systemBus, service, path,
2205 "xyz.openbmc_project.Control.Power.Mode",
2206 [asyncResp](
2207 const boost::system::error_code& ec2,
2208 const dbus::utility::DBusPropertiesMap& properties) {
2209 afterGetPowerMode(asyncResp, ec2, properties);
2210 });
George Liue99073f2022-12-09 11:06:16 +08002211 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002212}
2213
2214/**
2215 * @brief Validate the specified mode is valid and return the PowerMode
2216 * name associated with that string
2217 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002218 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002219 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002220 *
2221 * @return PowerMode value or empty string if mode is not valid
2222 */
2223inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002224 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002225 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002226{
Chris Cainb6655102024-02-01 14:35:33 -06002227 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002228 std::string mode;
2229
Chris Cainb6655102024-02-01 14:35:33 -06002230 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002231 {
2232 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2233 }
Chris Cainb6655102024-02-01 14:35:33 -06002234 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002235 {
George Liu0fda0f12021-11-16 10:06:17 +08002236 mode =
2237 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002238 }
Chris Cainb6655102024-02-01 14:35:33 -06002239 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002240 {
2241 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2242 }
Chris Cainb6655102024-02-01 14:35:33 -06002243 else if (modeValue == PowerMode::BalancedPerformance)
2244 {
2245 mode =
2246 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2247 }
2248 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2249 {
2250 mode =
2251 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2252 }
2253 else if (modeValue == PowerMode::EfficiencyFavorPower)
2254 {
2255 mode =
2256 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2257 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002258 else
2259 {
Chris Cainb6655102024-02-01 14:35:33 -06002260 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002261 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002262 }
2263 return mode;
2264}
2265
2266/**
2267 * @brief Sets system power mode.
2268 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002269 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002270 * @param[in] pmode System power mode from request.
2271 *
2272 * @return None.
2273 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002274inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002275 const std::string& pmode)
2276{
Ed Tanous62598e32023-07-17 17:06:25 -07002277 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002278
Ed Tanousac106bf2023-06-07 09:24:59 -07002279 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002280 if (powerMode.empty())
2281 {
2282 return;
2283 }
2284
2285 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002286 constexpr std::array<std::string_view, 1> interfaces = {
2287 "xyz.openbmc_project.Control.Power.Mode"};
2288 dbus::utility::getSubTree(
2289 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002290 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002291 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002292 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002293 if (ec)
2294 {
2295 BMCWEB_LOG_ERROR(
2296 "DBUS response error on Power.Mode GetSubTree {}", ec);
2297 // This is an optional D-Bus object, but user attempted to patch
2298 messages::internalError(asyncResp->res);
2299 return;
2300 }
2301 if (subtree.empty())
2302 {
2303 // This is an optional D-Bus object, but user attempted to patch
2304 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2305 "PowerMode");
2306 return;
2307 }
2308 if (subtree.size() > 1)
2309 {
2310 // More then one PowerMode object is not supported and is an
2311 // error
2312 BMCWEB_LOG_DEBUG(
2313 "Found more than 1 system D-Bus Power.Mode objects: {}",
2314 subtree.size());
2315 messages::internalError(asyncResp->res);
2316 return;
2317 }
2318 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2319 {
2320 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2321 messages::internalError(asyncResp->res);
2322 return;
2323 }
2324 const std::string& path = subtree[0].first;
2325 const std::string& service = subtree[0].second.begin()->first;
2326 if (service.empty())
2327 {
2328 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2329 messages::internalError(asyncResp->res);
2330 return;
2331 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002332
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002333 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002334
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002335 // Set the Power Mode property
2336 setDbusProperty(asyncResp, "PowerMode", service, path,
2337 "xyz.openbmc_project.Control.Power.Mode",
2338 "PowerMode", powerMode);
2339 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002340}
2341
2342/**
Yong Li51709ff2019-09-30 14:13:04 +08002343 * @brief Translates watchdog timeout action DBUS property value to redfish.
2344 *
2345 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2346 *
2347 * @return Returns as a string, the timeout action in Redfish terms. If
2348 * translation cannot be done, returns an empty string.
2349 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002350inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002351{
2352 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2353 {
2354 return "None";
2355 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002356 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002357 {
2358 return "ResetSystem";
2359 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002360 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002361 {
2362 return "PowerDown";
2363 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002364 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002365 {
2366 return "PowerCycle";
2367 }
2368
2369 return "";
2370}
2371
2372/**
Yong Lic45f0082019-10-10 14:19:01 +08002373 *@brief Translates timeout action from Redfish to DBUS property value.
2374 *
2375 *@param[in] rfAction The timeout action in Redfish.
2376 *
2377 *@return Returns as a string, the time_out action as expected by DBUS.
2378 *If translation cannot be done, returns an empty string.
2379 */
2380
Ed Tanous23a21a12020-07-25 04:45:05 +00002381inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002382{
2383 if (rfAction == "None")
2384 {
2385 return "xyz.openbmc_project.State.Watchdog.Action.None";
2386 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002387 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002388 {
2389 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2390 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002391 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002392 {
2393 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2394 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002395 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002396 {
2397 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2398 }
2399
2400 return "";
2401}
2402
2403/**
Yong Li51709ff2019-09-30 14:13:04 +08002404 * @brief Retrieves host watchdog timer properties over DBUS
2405 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002406 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002407 *
2408 * @return None.
2409 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002410inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002411 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002412{
Ed Tanous62598e32023-07-17 17:06:25 -07002413 BMCWEB_LOG_DEBUG("Get host watchodg");
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002414 sdbusplus::asio::getAllProperties(
2415 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2416 "/xyz/openbmc_project/watchdog/host0",
2417 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002418 [asyncResp](const boost::system::error_code& ec,
2419 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002420 if (ec)
2421 {
2422 // watchdog service is stopped
2423 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2424 return;
2425 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002426
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002427 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002428
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002429 nlohmann::json& hostWatchdogTimer =
2430 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002431
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002432 // watchdog service is running/enabled
2433 hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
Ed Tanous002d39b2022-05-31 08:59:27 -07002434
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002435 const bool* enabled = nullptr;
2436 const std::string* expireAction = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002437
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002438 const bool success = sdbusplus::unpackPropertiesNoThrow(
2439 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2440 enabled, "ExpireAction", expireAction);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002441
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002442 if (!success)
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002443 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002444 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002445 return;
2446 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002447
2448 if (enabled != nullptr)
2449 {
2450 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2451 }
2452
2453 if (expireAction != nullptr)
2454 {
2455 std::string action = dbusToRfWatchdogAction(*expireAction);
2456 if (action.empty())
2457 {
2458 messages::internalError(asyncResp->res);
2459 return;
2460 }
2461 hostWatchdogTimer["TimeoutAction"] = action;
2462 }
2463 });
Yong Li51709ff2019-09-30 14:13:04 +08002464}
2465
2466/**
Yong Lic45f0082019-10-10 14:19:01 +08002467 * @brief Sets Host WatchDog Timer properties.
2468 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002469 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002470 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2471 * RF request.
2472 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2473 *
2474 * @return None.
2475 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002476inline void
2477 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2478 const std::optional<bool> wdtEnable,
2479 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002480{
Ed Tanous62598e32023-07-17 17:06:25 -07002481 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002482
2483 if (wdtTimeOutAction)
2484 {
2485 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2486 // check if TimeOut Action is Valid
2487 if (wdtTimeOutActStr.empty())
2488 {
Ed Tanous62598e32023-07-17 17:06:25 -07002489 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2490 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002491 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002492 "TimeoutAction");
2493 return;
2494 }
2495
Ginu Georgee93abac2024-06-14 17:35:27 +05302496 setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2497 "xyz.openbmc_project.Watchdog",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00002498 sdbusplus::message::object_path(
2499 "/xyz/openbmc_project/watchdog/host0"),
2500 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ginu Georgee93abac2024-06-14 17:35:27 +05302501 wdtTimeOutActStr);
Yong Lic45f0082019-10-10 14:19:01 +08002502 }
2503
2504 if (wdtEnable)
2505 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302506 setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2507 "xyz.openbmc_project.Watchdog",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00002508 sdbusplus::message::object_path(
2509 "/xyz/openbmc_project/watchdog/host0"),
2510 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05302511 *wdtEnable);
Yong Lic45f0082019-10-10 14:19:01 +08002512 }
2513}
2514
Chris Cain37bbf982021-09-20 10:53:09 -05002515/**
2516 * @brief Parse the Idle Power Saver properties into json
2517 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002518 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002519 * @param[in] properties IPS property data from DBus.
2520 *
2521 * @return true if successful
2522 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002523inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002524 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002525 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002526{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002527 const bool* enabled = nullptr;
2528 const uint8_t* enterUtilizationPercent = nullptr;
2529 const uint64_t* enterDwellTime = nullptr;
2530 const uint8_t* exitUtilizationPercent = nullptr;
2531 const uint64_t* exitDwellTime = nullptr;
2532
2533 const bool success = sdbusplus::unpackPropertiesNoThrow(
2534 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002535 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2536 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2537 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002538
2539 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002540 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002541 return false;
2542 }
2543
2544 if (enabled != nullptr)
2545 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002546 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002547 }
2548
2549 if (enterUtilizationPercent != nullptr)
2550 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002551 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002552 *enterUtilizationPercent;
2553 }
2554
2555 if (enterDwellTime != nullptr)
2556 {
2557 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002558 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002559 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2560 .count();
2561 }
2562
2563 if (exitUtilizationPercent != nullptr)
2564 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002565 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002566 *exitUtilizationPercent;
2567 }
2568
2569 if (exitDwellTime != nullptr)
2570 {
2571 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002572 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002573 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2574 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002575 }
2576
2577 return true;
2578}
2579
2580/**
2581 * @brief Retrieves host watchdog timer properties over DBUS
2582 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002583 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002584 *
2585 * @return None.
2586 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002587inline void
2588 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002589{
Ed Tanous62598e32023-07-17 17:06:25 -07002590 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002591
2592 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002593 constexpr std::array<std::string_view, 1> interfaces = {
2594 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2595 dbus::utility::getSubTree(
2596 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002597 [asyncResp](const boost::system::error_code& ec,
2598 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002599 if (ec)
Chris Cain37bbf982021-09-20 10:53:09 -05002600 {
Ed Tanous62598e32023-07-17 17:06:25 -07002601 BMCWEB_LOG_ERROR(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002602 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2603 ec);
2604 messages::internalError(asyncResp->res);
2605 return;
2606 }
2607 if (subtree.empty())
2608 {
2609 // This is an optional interface so just return
2610 // if there is no instance found
2611 BMCWEB_LOG_DEBUG("No instances found");
2612 return;
2613 }
2614 if (subtree.size() > 1)
2615 {
2616 // More then one PowerIdlePowerSaver object is not supported and
2617 // is an error
2618 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2619 "Power.IdlePowerSaver objects: {}",
2620 subtree.size());
2621 messages::internalError(asyncResp->res);
2622 return;
2623 }
2624 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2625 {
2626 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2627 messages::internalError(asyncResp->res);
2628 return;
2629 }
2630 const std::string& path = subtree[0].first;
2631 const std::string& service = subtree[0].second.begin()->first;
2632 if (service.empty())
2633 {
2634 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002635 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002636 return;
2637 }
2638
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002639 // Valid IdlePowerSaver object found, now read the current values
2640 sdbusplus::asio::getAllProperties(
2641 *crow::connections::systemBus, service, path,
2642 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2643 [asyncResp](
2644 const boost::system::error_code& ec2,
2645 const dbus::utility::DBusPropertiesMap& properties) {
2646 if (ec2)
2647 {
2648 BMCWEB_LOG_ERROR(
2649 "DBUS response error on IdlePowerSaver GetAll: {}",
2650 ec2);
2651 messages::internalError(asyncResp->res);
2652 return;
2653 }
2654
2655 if (!parseIpsProperties(asyncResp, properties))
2656 {
2657 messages::internalError(asyncResp->res);
2658 return;
2659 }
2660 });
George Liue99073f2022-12-09 11:06:16 +08002661 });
Chris Cain37bbf982021-09-20 10:53:09 -05002662
Ed Tanous62598e32023-07-17 17:06:25 -07002663 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002664}
2665
2666/**
2667 * @brief Sets Idle Power Saver properties.
2668 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002669 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002670 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2671 * RF request.
2672 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2673 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2674 * before entering idle state.
2675 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2676 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2677 * before exiting idle state
2678 *
2679 * @return None.
2680 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002681inline void setIdlePowerSaver(
2682 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2683 const std::optional<bool> ipsEnable,
2684 const std::optional<uint8_t> ipsEnterUtil,
2685 const std::optional<uint64_t> ipsEnterTime,
2686 const std::optional<uint8_t> ipsExitUtil,
2687 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002688{
Ed Tanous62598e32023-07-17 17:06:25 -07002689 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002690
2691 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002692 constexpr std::array<std::string_view, 1> interfaces = {
2693 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2694 dbus::utility::getSubTree(
2695 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002696 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002697 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002698 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002699 if (ec)
2700 {
2701 BMCWEB_LOG_ERROR(
2702 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2703 ec);
2704 messages::internalError(asyncResp->res);
2705 return;
2706 }
2707 if (subtree.empty())
2708 {
2709 // This is an optional D-Bus object, but user attempted to patch
2710 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2711 "IdlePowerSaver");
2712 return;
2713 }
2714 if (subtree.size() > 1)
2715 {
2716 // More then one PowerIdlePowerSaver object is not supported and
2717 // is an error
2718 BMCWEB_LOG_DEBUG(
2719 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2720 subtree.size());
2721 messages::internalError(asyncResp->res);
2722 return;
2723 }
2724 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2725 {
2726 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2727 messages::internalError(asyncResp->res);
2728 return;
2729 }
2730 const std::string& path = subtree[0].first;
2731 const std::string& service = subtree[0].second.begin()->first;
2732 if (service.empty())
2733 {
2734 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2735 messages::internalError(asyncResp->res);
2736 return;
2737 }
Chris Cain37bbf982021-09-20 10:53:09 -05002738
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002739 // Valid Power IdlePowerSaver object found, now set any values that
2740 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002741
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002742 if (ipsEnable)
2743 {
2744 setDbusProperty(
2745 asyncResp, "IdlePowerSaver/Enabled", service, path,
2746 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2747 "Enabled", *ipsEnable);
2748 }
2749 if (ipsEnterUtil)
2750 {
2751 setDbusProperty(
2752 asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2753 service, path,
2754 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2755 "EnterUtilizationPercent", *ipsEnterUtil);
2756 }
2757 if (ipsEnterTime)
2758 {
2759 // Convert from seconds into milliseconds for DBus
2760 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2761 setDbusProperty(
2762 asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2763 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2764 "EnterDwellTime", timeMilliseconds);
2765 }
2766 if (ipsExitUtil)
2767 {
2768 setDbusProperty(
2769 asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2770 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2771 "ExitUtilizationPercent", *ipsExitUtil);
2772 }
2773 if (ipsExitTime)
2774 {
2775 // Convert from seconds into milliseconds for DBus
2776 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2777 setDbusProperty(
2778 asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2779 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2780 "ExitDwellTime", timeMilliseconds);
2781 }
2782 });
Chris Cain37bbf982021-09-20 10:53:09 -05002783
Ed Tanous62598e32023-07-17 17:06:25 -07002784 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002785}
2786
Ed Tanousc1e219d2023-06-07 10:34:33 -07002787inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002788 crow::App& app, const crow::Request& req,
2789 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2790{
2791 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2792 {
2793 return;
2794 }
2795 asyncResp->res.addHeader(
2796 boost::beast::http::field::link,
2797 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2798}
2799
Ed Tanousc1e219d2023-06-07 10:34:33 -07002800inline void handleComputerSystemCollectionGet(
2801 crow::App& app, const crow::Request& req,
2802 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2803{
2804 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2805 {
2806 return;
2807 }
2808
2809 asyncResp->res.addHeader(
2810 boost::beast::http::field::link,
2811 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2812 asyncResp->res.jsonValue["@odata.type"] =
2813 "#ComputerSystemCollection.ComputerSystemCollection";
2814 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2815 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2816
2817 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2818 ifaceArray = nlohmann::json::array();
Ed Tanous25b54db2024-04-17 15:40:31 -07002819 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002820 {
2821 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2822 // Option currently returns no systems. TBD
2823 return;
2824 }
2825 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2826 nlohmann::json::object_t system;
Ed Tanous253f11b2024-05-16 09:38:31 -07002827 system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2828 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002829 ifaceArray.emplace_back(std::move(system));
Gunnar Mills68896202024-08-21 11:34:20 -05002830
2831 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2832 {
2833 BMCWEB_LOG_DEBUG("Hypervisor is available");
2834 asyncResp->res.jsonValue["Members@odata.count"] = 2;
2835
2836 nlohmann::json::object_t hypervisor;
2837 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2838 ifaceArray.emplace_back(std::move(hypervisor));
2839 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07002840}
2841
Yong Lic45f0082019-10-10 14:19:01 +08002842/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002843 * Function transceives data with dbus directly.
2844 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002845inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002846{
Patrick Williams89492a12023-05-10 07:51:34 -05002847 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2848 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2849 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002850 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002851 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002852
2853 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002854 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002855 if (ec)
2856 {
2857 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
2858 messages::internalError(asyncResp->res);
2859 return;
2860 }
2861 messages::success(asyncResp->res);
2862 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002863 serviceName, objectPath, interfaceName, method);
2864}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002865
Ed Tanousc1e219d2023-06-07 10:34:33 -07002866inline void handleComputerSystemResetActionPost(
2867 crow::App& app, const crow::Request& req,
2868 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2869 const std::string& systemName)
2870{
2871 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2872 {
2873 return;
2874 }
Gunnar Millsdd7090e2024-07-30 15:23:05 -05002875
2876 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2877 {
2878 if (systemName == "hypervisor")
2879 {
2880 handleHypervisorSystemResetPost(req, asyncResp);
2881 return;
2882 }
2883 }
2884
Ed Tanous253f11b2024-05-16 09:38:31 -07002885 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002886 {
2887 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2888 systemName);
2889 return;
2890 }
Ed Tanous25b54db2024-04-17 15:40:31 -07002891 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002892 {
2893 // Option currently returns no systems. TBD
2894 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2895 systemName);
2896 return;
2897 }
2898 std::string resetType;
2899 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2900 {
2901 return;
2902 }
2903
2904 // Get the command and host vs. chassis
2905 std::string command;
2906 bool hostCommand = true;
2907 if ((resetType == "On") || (resetType == "ForceOn"))
2908 {
2909 command = "xyz.openbmc_project.State.Host.Transition.On";
2910 hostCommand = true;
2911 }
2912 else if (resetType == "ForceOff")
2913 {
2914 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2915 hostCommand = false;
2916 }
2917 else if (resetType == "ForceRestart")
2918 {
2919 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2920 hostCommand = true;
2921 }
2922 else if (resetType == "GracefulShutdown")
2923 {
2924 command = "xyz.openbmc_project.State.Host.Transition.Off";
2925 hostCommand = true;
2926 }
2927 else if (resetType == "GracefulRestart")
2928 {
2929 command =
2930 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2931 hostCommand = true;
2932 }
2933 else if (resetType == "PowerCycle")
2934 {
2935 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2936 hostCommand = true;
2937 }
2938 else if (resetType == "Nmi")
2939 {
2940 doNMI(asyncResp);
2941 return;
2942 }
2943 else
2944 {
2945 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2946 return;
2947 }
Ed Tanousd02aad32024-02-13 14:43:34 -08002948 sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002949
2950 if (hostCommand)
2951 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302952 setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
Ed Tanousd02aad32024-02-13 14:43:34 -08002953 statePath / "host0", "xyz.openbmc_project.State.Host",
Ginu Georgee93abac2024-06-14 17:35:27 +05302954 "RequestedHostTransition", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002955 }
2956 else
2957 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302958 setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
Ed Tanousd02aad32024-02-13 14:43:34 -08002959 statePath / "chassis0",
2960 "xyz.openbmc_project.State.Chassis",
Ginu Georgee93abac2024-06-14 17:35:27 +05302961 "RequestedPowerTransition", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002962 }
2963}
2964
Ed Tanousc1e219d2023-06-07 10:34:33 -07002965inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002966 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002967 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2968 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002969{
2970 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2971 {
2972 return;
2973 }
2974
2975 asyncResp->res.addHeader(
2976 boost::beast::http::field::link,
2977 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2978}
2979
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002980inline void afterPortRequest(
2981 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2982 const boost::system::error_code& ec,
2983 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
2984{
2985 if (ec)
2986 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002987 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002988 messages::internalError(asyncResp->res);
2989 return;
2990 }
2991 for (const auto& data : socketData)
2992 {
2993 const std::string& socketPath = get<0>(data);
2994 const std::string& protocolName = get<1>(data);
2995 bool isProtocolEnabled = get<2>(data);
2996 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
2997 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
2998 // need to retrieve port number for
2999 // obmc-console-ssh service
3000 if (protocolName == "SSH")
3001 {
3002 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07003003 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003004 int portNumber) {
3005 if (ec1)
3006 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05003007 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003008 messages::internalError(asyncResp->res);
3009 return;
3010 }
3011 nlohmann::json& dataJson1 =
3012 asyncResp->res.jsonValue["SerialConsole"];
3013 dataJson1[protocolName]["Port"] = portNumber;
3014 });
3015 }
3016 }
3017}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003018
3019inline void
3020 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3021 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3022 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003023{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003024 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3025 {
3026 return;
3027 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003028
Ed Tanous25b54db2024-04-17 15:40:31 -07003029 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003030 {
3031 // Option currently returns no systems. TBD
3032 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3033 systemName);
3034 return;
3035 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003036
Gunnar Mills68896202024-08-21 11:34:20 -05003037 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003038 {
Gunnar Mills68896202024-08-21 11:34:20 -05003039 if (systemName == "hypervisor")
3040 {
3041 handleHypervisorSystemGet(asyncResp);
3042 return;
3043 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003044 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003045
Ed Tanous253f11b2024-05-16 09:38:31 -07003046 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003047 {
3048 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3049 systemName);
3050 return;
3051 }
3052 asyncResp->res.addHeader(
3053 boost::beast::http::field::link,
3054 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3055 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003056 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanous253f11b2024-05-16 09:38:31 -07003057 asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3058 asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
Ed Tanous539d8c62024-06-19 14:38:27 -07003059 asyncResp->res.jsonValue["SystemType"] =
3060 computer_system::SystemType::Physical;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003061 asyncResp->res.jsonValue["Description"] = "Computer System";
3062 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003063 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003064 double(0);
Ed Tanous253f11b2024-05-16 09:38:31 -07003065 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3066 "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous04a258f2018-10-15 08:00:41 -07003067
Ed Tanous253f11b2024-05-16 09:38:31 -07003068 asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3069 "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3070 asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3071 "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3072 asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3073 "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003074 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003075 boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3076 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous029573d2019-02-01 10:57:49 -08003077
Ed Tanousc1e219d2023-06-07 10:34:33 -07003078 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003079 boost::urls::format(
3080 "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3081 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003082 asyncResp->res
3083 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003084 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3085 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003086
Ed Tanous253f11b2024-05-16 09:38:31 -07003087 asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3088 "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3089 asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3090 "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003091
Ed Tanousc1e219d2023-06-07 10:34:33 -07003092 nlohmann::json::array_t managedBy;
3093 nlohmann::json& manager = managedBy.emplace_back();
Ed Tanous253f11b2024-05-16 09:38:31 -07003094 manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3095 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003096 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
Ed Tanous539d8c62024-06-19 14:38:27 -07003097 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3098 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003099
Ed Tanousc1e219d2023-06-07 10:34:33 -07003100 // Fill in SerialConsole info
3101 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3102 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003103
Ed Tanousc1e219d2023-06-07 10:34:33 -07003104 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3105 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3106 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3107 "Press ~. to exit console";
3108 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3109 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003110
Ed Tanous25b54db2024-04-17 15:40:31 -07003111 if constexpr (BMCWEB_KVM)
3112 {
3113 // Fill in GraphicalConsole info
3114 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3115 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3116 4;
3117 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3118 nlohmann::json::array_t({"KVMIP"});
3119 }
James Feistb49ac872019-05-21 15:12:01 -07003120
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003121 getMainChassisId(
3122 asyncResp, [](const std::string& chassisId,
3123 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3124 nlohmann::json::array_t chassisArray;
3125 nlohmann::json& chassis = chassisArray.emplace_back();
3126 chassis["@odata.id"] =
3127 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
3128 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3129 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003130
George Liu59a17e42022-10-08 09:27:47 +08003131 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003132 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3133 getIndicatorLedState(asyncResp);
Gunnar Mills51bd2d82024-04-01 15:25:51 -05003134 getComputerSystem(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003135 getHostState(asyncResp);
3136 getBootProperties(asyncResp);
3137 getBootProgress(asyncResp);
3138 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003139 pcie_util::getPCIeDeviceList(asyncResp,
3140 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003141 getHostWatchdogTimer(asyncResp);
3142 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003143 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003144 getAutomaticRetryPolicy(asyncResp);
3145 getLastResetTime(asyncResp);
Ed Tanous25b54db2024-04-17 15:40:31 -07003146 if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
3147 {
3148 getProvisioningStatus(asyncResp);
3149 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003150 getTrustedModuleRequiredToBoot(asyncResp);
3151 getPowerMode(asyncResp);
3152 getIdlePowerSaver(asyncResp);
3153}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003154
Ed Tanousc1e219d2023-06-07 10:34:33 -07003155inline void handleComputerSystemPatch(
3156 crow::App& app, const crow::Request& req,
3157 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3158 const std::string& systemName)
3159{
3160 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3161 {
3162 return;
3163 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003164 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003165 {
3166 // Option currently returns no systems. TBD
3167 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3168 systemName);
3169 return;
3170 }
Ed Tanous253f11b2024-05-16 09:38:31 -07003171 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003172 {
3173 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3174 systemName);
3175 return;
3176 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003177
Ed Tanousc1e219d2023-06-07 10:34:33 -07003178 asyncResp->res.addHeader(
3179 boost::beast::http::field::link,
3180 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003181
Ed Tanousc1e219d2023-06-07 10:34:33 -07003182 std::optional<bool> locationIndicatorActive;
3183 std::optional<std::string> indicatorLed;
3184 std::optional<std::string> assetTag;
3185 std::optional<std::string> powerRestorePolicy;
3186 std::optional<std::string> powerMode;
3187 std::optional<bool> wdtEnable;
3188 std::optional<std::string> wdtTimeOutAction;
3189 std::optional<std::string> bootSource;
3190 std::optional<std::string> bootType;
3191 std::optional<std::string> bootEnable;
3192 std::optional<std::string> bootAutomaticRetry;
3193 std::optional<uint32_t> bootAutomaticRetryAttempts;
3194 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003195 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003196 std::optional<bool> ipsEnable;
3197 std::optional<uint8_t> ipsEnterUtil;
3198 std::optional<uint64_t> ipsEnterTime;
3199 std::optional<uint8_t> ipsExitUtil;
3200 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003201
Myung Baeafc474a2024-10-09 00:53:29 -07003202 if (!json_util::readJsonPatch( //
3203 req, asyncResp->res, //
3204 "AssetTag", assetTag, //
3205 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, //
3206 "Boot/AutomaticRetryConfig", bootAutomaticRetry, //
3207 "Boot/BootSourceOverrideEnabled", bootEnable, //
3208 "Boot/BootSourceOverrideMode", bootType, //
3209 "Boot/BootSourceOverrideTarget", bootSource, //
3210 "Boot/StopBootOnFault", stopBootOnFault, //
3211 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, //
3212 "HostWatchdogTimer/FunctionEnabled", wdtEnable, //
3213 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, //
3214 "IdlePowerSaver/Enabled", ipsEnable, //
3215 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, //
3216 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, //
3217 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, //
3218 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, //
3219 "IndicatorLED", indicatorLed, //
3220 "LocationIndicatorActive", locationIndicatorActive, //
3221 "PowerMode", powerMode, //
3222 "PowerRestorePolicy", powerRestorePolicy //
3223 ))
Ed Tanousab344222024-08-07 18:01:23 -07003224 {
3225 return;
3226 }
James Feistb49ac872019-05-21 15:12:01 -07003227
Ed Tanousc1e219d2023-06-07 10:34:33 -07003228 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003229
Ed Tanousc1e219d2023-06-07 10:34:33 -07003230 if (assetTag)
3231 {
3232 setAssetTag(asyncResp, *assetTag);
3233 }
James Feistb49ac872019-05-21 15:12:01 -07003234
Ed Tanousc1e219d2023-06-07 10:34:33 -07003235 if (wdtEnable || wdtTimeOutAction)
3236 {
3237 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3238 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003239
Ed Tanousc1e219d2023-06-07 10:34:33 -07003240 if (bootSource || bootType || bootEnable)
3241 {
3242 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3243 }
3244 if (bootAutomaticRetry)
3245 {
3246 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3247 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003248
Ed Tanousc1e219d2023-06-07 10:34:33 -07003249 if (bootAutomaticRetryAttempts)
3250 {
3251 setAutomaticRetryAttempts(asyncResp,
3252 bootAutomaticRetryAttempts.value());
3253 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003254
Ed Tanousc1e219d2023-06-07 10:34:33 -07003255 if (bootTrustedModuleRequired)
3256 {
3257 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3258 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003259
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003260 if (stopBootOnFault)
3261 {
3262 setStopBootOnFault(asyncResp, *stopBootOnFault);
3263 }
3264
Ed Tanousc1e219d2023-06-07 10:34:33 -07003265 if (locationIndicatorActive)
3266 {
George Liu59a17e42022-10-08 09:27:47 +08003267 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003268 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003269
Ed Tanousc1e219d2023-06-07 10:34:33 -07003270 // TODO (Gunnar): Remove IndicatorLED after enough time has
3271 // passed
3272 if (indicatorLed)
3273 {
3274 setIndicatorLedState(asyncResp, *indicatorLed);
3275 asyncResp->res.addHeader(boost::beast::http::field::warning,
3276 "299 - \"IndicatorLED is deprecated. Use "
3277 "LocationIndicatorActive instead.\"");
3278 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003279
Ed Tanousc1e219d2023-06-07 10:34:33 -07003280 if (powerRestorePolicy)
3281 {
3282 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3283 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003284
Ed Tanousc1e219d2023-06-07 10:34:33 -07003285 if (powerMode)
3286 {
3287 setPowerMode(asyncResp, *powerMode);
3288 }
Chris Cain37bbf982021-09-20 10:53:09 -05003289
Ed Tanousc1e219d2023-06-07 10:34:33 -07003290 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3291 {
3292 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3293 ipsExitUtil, ipsExitTime);
3294 }
3295}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303296
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003297inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003298 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003299 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003300 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003301{
3302 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3303 {
3304 return;
3305 }
3306 asyncResp->res.addHeader(
3307 boost::beast::http::field::link,
3308 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3309}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003310
3311/**
3312 * @brief Translates allowed host transitions to redfish string
3313 *
3314 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3315 * @param[out] allowableValues The translated host transition(s)
3316 *
Manojkiran Edaefff2b52024-06-18 18:01:46 +05303317 * @return Emplaces corresponding Redfish translated value(s) in
Andrew Geissler33e1f122024-02-26 21:10:16 -06003318 * allowableValues. If translation not possible, does nothing to
3319 * allowableValues.
3320 */
3321inline void
3322 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3323 nlohmann::json::array_t& allowableValues)
3324{
3325 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3326 {
3327 allowableValues.emplace_back(resource::ResetType::On);
3328 allowableValues.emplace_back(resource::ResetType::ForceOn);
3329 }
3330 else if (dbusAllowedHostTran ==
3331 "xyz.openbmc_project.State.Host.Transition.Off")
3332 {
3333 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3334 }
3335 else if (dbusAllowedHostTran ==
3336 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3337 {
3338 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3339 }
3340 else if (dbusAllowedHostTran ==
3341 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3342 {
3343 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3344 }
3345 else
3346 {
3347 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3348 }
3349}
3350
3351inline void afterGetAllowedHostTransitions(
3352 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3353 const boost::system::error_code& ec,
3354 const std::vector<std::string>& allowedHostTransitions)
3355{
3356 nlohmann::json::array_t allowableValues;
3357
3358 // Supported on all systems currently
3359 allowableValues.emplace_back(resource::ResetType::ForceOff);
3360 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3361 allowableValues.emplace_back(resource::ResetType::Nmi);
3362
3363 if (ec)
3364 {
Ed Tanouse715d142024-03-07 15:47:37 -08003365 if ((ec.value() ==
3366 boost::system::linux_error::bad_request_descriptor) ||
3367 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003368 {
3369 // Property not implemented so just return defaults
3370 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3371 allowableValues.emplace_back(resource::ResetType::On);
3372 allowableValues.emplace_back(resource::ResetType::ForceOn);
3373 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3374 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3375 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3376 }
3377 else
3378 {
3379 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3380 messages::internalError(asyncResp->res);
3381 return;
3382 }
3383 }
3384 else
3385 {
3386 for (const std::string& transition : allowedHostTransitions)
3387 {
3388 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3389 dbusToRfAllowedHostTransitions(transition, allowableValues);
3390 }
3391 }
3392
3393 nlohmann::json::object_t parameter;
3394 parameter["Name"] = "ResetType";
3395 parameter["Required"] = true;
Ed Tanous539d8c62024-06-19 14:38:27 -07003396 parameter["DataType"] = action_info::ParameterTypes::String;
Andrew Geissler33e1f122024-02-26 21:10:16 -06003397 parameter["AllowableValues"] = std::move(allowableValues);
3398 nlohmann::json::array_t parameters;
3399 parameters.emplace_back(std::move(parameter));
3400 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3401}
3402
Ed Tanousc1e219d2023-06-07 10:34:33 -07003403inline void handleSystemCollectionResetActionGet(
3404 crow::App& app, const crow::Request& req,
3405 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3406 const std::string& systemName)
3407{
3408 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3409 {
3410 return;
3411 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003412 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003413 {
3414 // Option currently returns no systems. TBD
3415 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3416 systemName);
3417 return;
3418 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003419
Gunnar Mills68896202024-08-21 11:34:20 -05003420 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003421 {
Gunnar Mills68896202024-08-21 11:34:20 -05003422 if (systemName == "hypervisor")
3423 {
3424 handleHypervisorResetActionGet(asyncResp);
3425 return;
3426 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003427 }
3428
Ed Tanous253f11b2024-05-16 09:38:31 -07003429 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003430 {
3431 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3432 systemName);
3433 return;
3434 }
3435
3436 asyncResp->res.addHeader(
3437 boost::beast::http::field::link,
3438 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3439
3440 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003441 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3442 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003443 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3444 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3445 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3446
Andrew Geissler33e1f122024-02-26 21:10:16 -06003447 // Look to see if system defines AllowedHostTransitions
3448 sdbusplus::asio::getProperty<std::vector<std::string>>(
3449 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3450 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
3451 "AllowedHostTransitions",
3452 [asyncResp](const boost::system::error_code& ec,
3453 const std::vector<std::string>& allowedHostTransitions) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003454 afterGetAllowedHostTransitions(asyncResp, ec,
3455 allowedHostTransitions);
3456 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003457}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303458/**
3459 * SystemResetActionInfo derived class for delivering Computer Systems
3460 * ResetType AllowableValues using ResetInfo schema.
3461 */
Ed Tanous100afe52023-06-07 13:30:46 -07003462inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303463{
Ed Tanous100afe52023-06-07 13:30:46 -07003464 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3465 .privileges(redfish::privileges::headComputerSystemCollection)
3466 .methods(boost::beast::http::verb::head)(
3467 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3468
3469 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3470 .privileges(redfish::privileges::getComputerSystemCollection)
3471 .methods(boost::beast::http::verb::get)(
3472 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3473
3474 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3475 .privileges(redfish::privileges::headComputerSystem)
3476 .methods(boost::beast::http::verb::head)(
3477 std::bind_front(handleComputerSystemHead, std::ref(app)));
3478
3479 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3480 .privileges(redfish::privileges::getComputerSystem)
3481 .methods(boost::beast::http::verb::get)(
3482 std::bind_front(handleComputerSystemGet, std::ref(app)));
3483
3484 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3485 .privileges(redfish::privileges::patchComputerSystem)
3486 .methods(boost::beast::http::verb::patch)(
3487 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3488
3489 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3490 .privileges(redfish::privileges::postComputerSystem)
3491 .methods(boost::beast::http::verb::post)(std::bind_front(
3492 handleComputerSystemResetActionPost, std::ref(app)));
3493
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003494 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003495 .privileges(redfish::privileges::headActionInfo)
3496 .methods(boost::beast::http::verb::head)(std::bind_front(
3497 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003498 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003499 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003500 .methods(boost::beast::http::verb::get)(std::bind_front(
3501 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003502}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003503} // namespace redfish