blob: 4ad92ddcde6fd7027319186a15c632f9fea74d9e [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed 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
Ed Tanousc1e219d2023-06-07 10:34:33 -07003202 // clang-format off
Ed Tanousab344222024-08-07 18:01:23 -07003203 if (!json_util::readJsonPatch(
3204 req, asyncResp->res,
3205 "IndicatorLED", indicatorLed,
3206 "LocationIndicatorActive", locationIndicatorActive,
3207 "AssetTag", assetTag,
3208 "PowerRestorePolicy", powerRestorePolicy,
3209 "PowerMode", powerMode,
3210 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3211 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3212 "Boot/BootSourceOverrideTarget", bootSource,
3213 "Boot/BootSourceOverrideMode", bootType,
3214 "Boot/BootSourceOverrideEnabled", bootEnable,
3215 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3216 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts,
3217 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3218 "Boot/StopBootOnFault", stopBootOnFault,
3219 "IdlePowerSaver/Enabled", ipsEnable,
3220 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3221 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3222 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3223 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3224 {
3225 return;
3226 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003227 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003228
Ed Tanousc1e219d2023-06-07 10:34:33 -07003229 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003230
Ed Tanousc1e219d2023-06-07 10:34:33 -07003231 if (assetTag)
3232 {
3233 setAssetTag(asyncResp, *assetTag);
3234 }
James Feistb49ac872019-05-21 15:12:01 -07003235
Ed Tanousc1e219d2023-06-07 10:34:33 -07003236 if (wdtEnable || wdtTimeOutAction)
3237 {
3238 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3239 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003240
Ed Tanousc1e219d2023-06-07 10:34:33 -07003241 if (bootSource || bootType || bootEnable)
3242 {
3243 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3244 }
3245 if (bootAutomaticRetry)
3246 {
3247 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3248 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003249
Ed Tanousc1e219d2023-06-07 10:34:33 -07003250 if (bootAutomaticRetryAttempts)
3251 {
3252 setAutomaticRetryAttempts(asyncResp,
3253 bootAutomaticRetryAttempts.value());
3254 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003255
Ed Tanousc1e219d2023-06-07 10:34:33 -07003256 if (bootTrustedModuleRequired)
3257 {
3258 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3259 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003260
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003261 if (stopBootOnFault)
3262 {
3263 setStopBootOnFault(asyncResp, *stopBootOnFault);
3264 }
3265
Ed Tanousc1e219d2023-06-07 10:34:33 -07003266 if (locationIndicatorActive)
3267 {
George Liu59a17e42022-10-08 09:27:47 +08003268 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003269 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003270
Ed Tanousc1e219d2023-06-07 10:34:33 -07003271 // TODO (Gunnar): Remove IndicatorLED after enough time has
3272 // passed
3273 if (indicatorLed)
3274 {
3275 setIndicatorLedState(asyncResp, *indicatorLed);
3276 asyncResp->res.addHeader(boost::beast::http::field::warning,
3277 "299 - \"IndicatorLED is deprecated. Use "
3278 "LocationIndicatorActive instead.\"");
3279 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003280
Ed Tanousc1e219d2023-06-07 10:34:33 -07003281 if (powerRestorePolicy)
3282 {
3283 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3284 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003285
Ed Tanousc1e219d2023-06-07 10:34:33 -07003286 if (powerMode)
3287 {
3288 setPowerMode(asyncResp, *powerMode);
3289 }
Chris Cain37bbf982021-09-20 10:53:09 -05003290
Ed Tanousc1e219d2023-06-07 10:34:33 -07003291 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3292 {
3293 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3294 ipsExitUtil, ipsExitTime);
3295 }
3296}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303297
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003298inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003299 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003300 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003301 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003302{
3303 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3304 {
3305 return;
3306 }
3307 asyncResp->res.addHeader(
3308 boost::beast::http::field::link,
3309 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3310}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003311
3312/**
3313 * @brief Translates allowed host transitions to redfish string
3314 *
3315 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3316 * @param[out] allowableValues The translated host transition(s)
3317 *
Manojkiran Edaefff2b52024-06-18 18:01:46 +05303318 * @return Emplaces corresponding Redfish translated value(s) in
Andrew Geissler33e1f122024-02-26 21:10:16 -06003319 * allowableValues. If translation not possible, does nothing to
3320 * allowableValues.
3321 */
3322inline void
3323 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3324 nlohmann::json::array_t& allowableValues)
3325{
3326 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3327 {
3328 allowableValues.emplace_back(resource::ResetType::On);
3329 allowableValues.emplace_back(resource::ResetType::ForceOn);
3330 }
3331 else if (dbusAllowedHostTran ==
3332 "xyz.openbmc_project.State.Host.Transition.Off")
3333 {
3334 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3335 }
3336 else if (dbusAllowedHostTran ==
3337 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3338 {
3339 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3340 }
3341 else if (dbusAllowedHostTran ==
3342 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3343 {
3344 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3345 }
3346 else
3347 {
3348 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3349 }
3350}
3351
3352inline void afterGetAllowedHostTransitions(
3353 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3354 const boost::system::error_code& ec,
3355 const std::vector<std::string>& allowedHostTransitions)
3356{
3357 nlohmann::json::array_t allowableValues;
3358
3359 // Supported on all systems currently
3360 allowableValues.emplace_back(resource::ResetType::ForceOff);
3361 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3362 allowableValues.emplace_back(resource::ResetType::Nmi);
3363
3364 if (ec)
3365 {
Ed Tanouse715d142024-03-07 15:47:37 -08003366 if ((ec.value() ==
3367 boost::system::linux_error::bad_request_descriptor) ||
3368 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003369 {
3370 // Property not implemented so just return defaults
3371 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3372 allowableValues.emplace_back(resource::ResetType::On);
3373 allowableValues.emplace_back(resource::ResetType::ForceOn);
3374 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3375 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3376 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3377 }
3378 else
3379 {
3380 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3381 messages::internalError(asyncResp->res);
3382 return;
3383 }
3384 }
3385 else
3386 {
3387 for (const std::string& transition : allowedHostTransitions)
3388 {
3389 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3390 dbusToRfAllowedHostTransitions(transition, allowableValues);
3391 }
3392 }
3393
3394 nlohmann::json::object_t parameter;
3395 parameter["Name"] = "ResetType";
3396 parameter["Required"] = true;
Ed Tanous539d8c62024-06-19 14:38:27 -07003397 parameter["DataType"] = action_info::ParameterTypes::String;
Andrew Geissler33e1f122024-02-26 21:10:16 -06003398 parameter["AllowableValues"] = std::move(allowableValues);
3399 nlohmann::json::array_t parameters;
3400 parameters.emplace_back(std::move(parameter));
3401 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3402}
3403
Ed Tanousc1e219d2023-06-07 10:34:33 -07003404inline void handleSystemCollectionResetActionGet(
3405 crow::App& app, const crow::Request& req,
3406 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3407 const std::string& systemName)
3408{
3409 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3410 {
3411 return;
3412 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003413 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003414 {
3415 // Option currently returns no systems. TBD
3416 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3417 systemName);
3418 return;
3419 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003420
Gunnar Mills68896202024-08-21 11:34:20 -05003421 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003422 {
Gunnar Mills68896202024-08-21 11:34:20 -05003423 if (systemName == "hypervisor")
3424 {
3425 handleHypervisorResetActionGet(asyncResp);
3426 return;
3427 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003428 }
3429
Ed Tanous253f11b2024-05-16 09:38:31 -07003430 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003431 {
3432 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3433 systemName);
3434 return;
3435 }
3436
3437 asyncResp->res.addHeader(
3438 boost::beast::http::field::link,
3439 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3440
3441 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003442 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3443 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003444 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3445 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3446 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3447
Andrew Geissler33e1f122024-02-26 21:10:16 -06003448 // Look to see if system defines AllowedHostTransitions
3449 sdbusplus::asio::getProperty<std::vector<std::string>>(
3450 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
3451 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
3452 "AllowedHostTransitions",
3453 [asyncResp](const boost::system::error_code& ec,
3454 const std::vector<std::string>& allowedHostTransitions) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003455 afterGetAllowedHostTransitions(asyncResp, ec,
3456 allowedHostTransitions);
3457 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003458}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303459/**
3460 * SystemResetActionInfo derived class for delivering Computer Systems
3461 * ResetType AllowableValues using ResetInfo schema.
3462 */
Ed Tanous100afe52023-06-07 13:30:46 -07003463inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303464{
Ed Tanous100afe52023-06-07 13:30:46 -07003465 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3466 .privileges(redfish::privileges::headComputerSystemCollection)
3467 .methods(boost::beast::http::verb::head)(
3468 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3469
3470 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3471 .privileges(redfish::privileges::getComputerSystemCollection)
3472 .methods(boost::beast::http::verb::get)(
3473 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3474
3475 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3476 .privileges(redfish::privileges::headComputerSystem)
3477 .methods(boost::beast::http::verb::head)(
3478 std::bind_front(handleComputerSystemHead, std::ref(app)));
3479
3480 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3481 .privileges(redfish::privileges::getComputerSystem)
3482 .methods(boost::beast::http::verb::get)(
3483 std::bind_front(handleComputerSystemGet, std::ref(app)));
3484
3485 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3486 .privileges(redfish::privileges::patchComputerSystem)
3487 .methods(boost::beast::http::verb::patch)(
3488 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3489
3490 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3491 .privileges(redfish::privileges::postComputerSystem)
3492 .methods(boost::beast::http::verb::post)(std::bind_front(
3493 handleComputerSystemResetActionPost, std::ref(app)));
3494
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003495 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003496 .privileges(redfish::privileges::headActionInfo)
3497 .methods(boost::beast::http::verb::head)(std::bind_front(
3498 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003499 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003500 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003501 .methods(boost::beast::http::verb::get)(std::bind_front(
3502 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003503}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003504} // namespace redfish