blob: e04bb8aa099321ad6de0d8f7337e589cec6da996 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020015*/
16#pragma once
17
Willy Tu13451e32023-05-24 16:08:18 -070018#include "bmcweb_config.h"
19
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080020#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070021#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080022#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070023#include "generated/enums/action_info.hpp"
Ed Tanous8d69c662023-06-21 10:29:06 -070024#include "generated/enums/computer_system.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070025#include "generated/enums/open_bmc_computer_system.hpp"
Andrew Geissler33e1f122024-02-26 21:10:16 -060026#include "generated/enums/resource.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060027#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080028#include "led.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070029#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080030#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080031#include "registries/privilege_registry.hpp"
32#include "utils/dbus_utils.hpp"
33#include "utils/json_utils.hpp"
Lakshmi Yadlapati472bd202023-03-22 09:57:05 -050034#include "utils/pcie_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080035#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070036#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080037
Andrew Geisslerfc903b32023-05-31 14:15:42 -040038#include <boost/asio/error.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070039#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080040#include <boost/system/error_code.hpp>
Andrew Geissler33e1f122024-02-26 21:10:16 -060041#include <boost/system/linux_error.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070042#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070043#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040044#include <sdbusplus/message.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020045#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050046
George Liu7a1dbc42022-12-07 16:03:22 +080047#include <array>
Andrew Geissler33e1f122024-02-26 21:10:16 -060048#include <memory>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060049#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080050#include <string_view>
Ed Tanous20fa6a22024-05-20 18:02:58 -070051#include <utility>
Ed Tanousabf2add2019-01-22 16:40:12 -080052#include <variant>
Chris Cain6b9ac4f2024-02-15 12:59:32 -060053#include <vector>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020054
Ed Tanous1abe55e2018-09-05 08:30:59 -070055namespace redfish
56{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020057
Abhishek Patel5c3e9272021-06-24 10:11:33 -050058const static std::array<std::pair<std::string_view, std::string_view>, 2>
59 protocolToDBusForSystems{
60 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
61
Alpana Kumari9d3ae102019-04-12 06:49:32 -050062/**
63 * @brief Updates the Functional State of DIMMs
64 *
Ed Tanousac106bf2023-06-07 09:24:59 -070065 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari9d3ae102019-04-12 06:49:32 -050066 * @param[in] dimmState Dimm's Functional state, true/false
67 *
68 * @return None.
69 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -040070inline void updateDimmProperties(
71 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050072{
Ed Tanous62598e32023-07-17 17:06:25 -070073 BMCWEB_LOG_DEBUG("Dimm Functional: {}", isDimmFunctional);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050074
Gunnar Mills4e0453b2020-07-08 14:00:30 -050075 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050076 // Update STATE only if previous State was DISABLED and current Dimm is
77 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070078 const nlohmann::json& prevMemSummary =
Ed Tanousac106bf2023-06-07 09:24:59 -070079 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"];
Alpana Kumari9d3ae102019-04-12 06:49:32 -050080 if (prevMemSummary == "Disabled")
81 {
Ed Tanouse05aec52022-01-25 10:28:56 -080082 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050083 {
Ed Tanousac106bf2023-06-07 09:24:59 -070084 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050085 "Enabled";
86 }
87 }
88}
89
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050090/*
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050091 * @brief Update "ProcessorSummary" "Status" "State" based on
92 * CPU Functional State
93 *
Ed Tanousac106bf2023-06-07 09:24:59 -070094 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050095 * @param[in] cpuFunctionalState is CPU functional true/false
96 *
97 * @return None.
98 */
Ed Tanousac106bf2023-06-07 09:24:59 -070099inline void modifyCpuFunctionalState(
100 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500101{
Ed Tanous62598e32023-07-17 17:06:25 -0700102 BMCWEB_LOG_DEBUG("Cpu Functional: {}", isCpuFunctional);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500103
Ed Tanous02cad962022-06-30 16:50:15 -0700104 const nlohmann::json& prevProcState =
Ed Tanousac106bf2023-06-07 09:24:59 -0700105 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500106
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500107 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500108 // Update STATE only if previous State was Non_Functional and current CPU is
109 // Functional.
110 if (prevProcState == "Disabled")
111 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800112 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700114 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115 "Enabled";
116 }
117 }
118}
119
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500120/*
121 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
122 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700123 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500124 * @param[in] cpuPresenceState CPU present or not
125 *
126 * @return None.
127 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400128inline void modifyCpuPresenceState(
129 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, bool isCpuPresent)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500130{
Ed Tanous62598e32023-07-17 17:06:25 -0700131 BMCWEB_LOG_DEBUG("Cpu Present: {}", isCpuPresent);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500132
133 if (isCpuPresent)
134 {
135 nlohmann::json& procCount =
Ed Tanousac106bf2023-06-07 09:24:59 -0700136 asyncResp->res.jsonValue["ProcessorSummary"]["Count"];
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500137 auto* procCountPtr =
138 procCount.get_ptr<nlohmann::json::number_integer_t*>();
139 if (procCountPtr != nullptr)
140 {
141 // shouldn't be possible to be nullptr
142 *procCountPtr += 1;
143 }
144 }
145}
146
Ali Ahmed382d6472021-09-03 16:53:53 -0500147inline void getProcessorProperties(
Ed Tanousac106bf2023-06-07 09:24:59 -0700148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ali Ahmed382d6472021-09-03 16:53:53 -0500149 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
150 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500151{
Ed Tanous62598e32023-07-17 17:06:25 -0700152 BMCWEB_LOG_DEBUG("Got {} Cpu properties.", properties.size());
Ali Ahmed03fbed92021-09-03 02:33:43 -0500153
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200154 // TODO: Get Model
155
156 const uint16_t* coreCount = nullptr;
157
158 const bool success = sdbusplus::unpackPropertiesNoThrow(
159 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
160
161 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500162 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700163 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200164 return;
165 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500166
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200167 if (coreCount != nullptr)
168 {
169 nlohmann::json& coreCountJson =
Ed Tanousac106bf2023-06-07 09:24:59 -0700170 asyncResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200171 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500172
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200173 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500174 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200175 coreCountJson = *coreCount;
176 }
177 else
178 {
179 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500180 }
181 }
182}
183
184/*
185 * @brief Get ProcessorSummary fields
186 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ali Ahmed03fbed92021-09-03 02:33:43 -0500188 * @param[in] service dbus service for Cpu Information
189 * @param[in] path dbus path for Cpu
190 *
191 * @return None.
192 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700193inline void
194 getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
195 const std::string& service, const std::string& path)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500196{
Ed Tanousac106bf2023-06-07 09:24:59 -0700197 auto getCpuPresenceState = [asyncResp](const boost::system::error_code& ec3,
198 const bool cpuPresenceCheck) {
Ali Ahmed382d6472021-09-03 16:53:53 -0500199 if (ec3)
200 {
Ed Tanous62598e32023-07-17 17:06:25 -0700201 BMCWEB_LOG_ERROR("DBUS response error {}", ec3);
Ali Ahmed382d6472021-09-03 16:53:53 -0500202 return;
203 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700204 modifyCpuPresenceState(asyncResp, cpuPresenceCheck);
Ali Ahmed382d6472021-09-03 16:53:53 -0500205 };
206
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500207 // Get the Presence of CPU
Ed Tanousdeae6a72024-11-11 21:58:57 -0800208 dbus::utility::getProperty<bool>(*crow::connections::systemBus, service,
209 path, "xyz.openbmc_project.Inventory.Item",
210 "Present", std::move(getCpuPresenceState));
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500211
Ed Tanousdeae6a72024-11-11 21:58:57 -0800212 dbus::utility::getAllProperties(
213 service, path, "xyz.openbmc_project.Inventory.Item.Cpu",
Ed Tanousac106bf2023-06-07 09:24:59 -0700214 [asyncResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800215 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800216 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400217 if (ec2)
218 {
219 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
220 messages::internalError(asyncResp->res);
221 return;
222 }
223 getProcessorProperties(asyncResp, properties);
224 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500225}
226
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500227/*
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500228 * @brief processMemoryProperties fields
229 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700230 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500231 * @param[in] DBUS properties for memory
232 *
233 * @return None.
234 */
235inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700236 processMemoryProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500237 const dbus::utility::DBusPropertiesMap& properties)
238{
Ed Tanous62598e32023-07-17 17:06:25 -0700239 BMCWEB_LOG_DEBUG("Got {} Dimm properties.", properties.size());
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500240
241 if (properties.empty())
242 {
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500243 return;
244 }
245
246 const size_t* memorySizeInKB = nullptr;
247
248 const bool success = sdbusplus::unpackPropertiesNoThrow(
249 dbus_utils::UnpackErrorPrinter(), properties, "MemorySizeInKB",
250 memorySizeInKB);
251
252 if (!success)
253 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700254 messages::internalError(asyncResp->res);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500255 return;
256 }
257
258 if (memorySizeInKB != nullptr)
259 {
260 nlohmann::json& totalMemory =
Ed Tanousac106bf2023-06-07 09:24:59 -0700261 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"];
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500262 const double* preValue = totalMemory.get_ptr<const double*>();
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500263 if (preValue == nullptr)
264 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700265 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500266 static_cast<double>(*memorySizeInKB) / (1024 * 1024);
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500267 }
268 else
269 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700270 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -0500271 static_cast<double>(*memorySizeInKB) / (1024 * 1024) +
272 *preValue;
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500273 }
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500274 }
275}
276
277/*
278 * @brief Get getMemorySummary fields
279 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700280 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500281 * @param[in] service dbus service for memory Information
282 * @param[in] path dbus path for memory
283 *
284 * @return None.
285 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700286inline void
287 getMemorySummary(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
288 const std::string& service, const std::string& path)
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500289{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800290 dbus::utility::getAllProperties(
291 service, path, "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanousac106bf2023-06-07 09:24:59 -0700292 [asyncResp, service,
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500293 path](const boost::system::error_code& ec2,
294 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400295 if (ec2)
296 {
297 BMCWEB_LOG_ERROR("DBUS response error {}", ec2);
298 messages::internalError(asyncResp->res);
299 return;
300 }
301 processMemoryProperties(asyncResp, properties);
302 });
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500303}
304
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500305inline void afterGetUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
306 const boost::system::error_code& ec,
307 const dbus::utility::DBusPropertiesMap& properties)
308{
309 if (ec)
310 {
311 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
312 messages::internalError(asyncResp->res);
313 return;
314 }
315 BMCWEB_LOG_DEBUG("Got {} UUID properties.", properties.size());
316
317 const std::string* uUID = nullptr;
318
319 const bool success = sdbusplus::unpackPropertiesNoThrow(
320 dbus_utils::UnpackErrorPrinter(), properties, "UUID", uUID);
321
322 if (!success)
323 {
324 messages::internalError(asyncResp->res);
325 return;
326 }
327
328 if (uUID != nullptr)
329 {
330 std::string valueStr = *uUID;
331 if (valueStr.size() == 32)
332 {
333 valueStr.insert(8, 1, '-');
334 valueStr.insert(13, 1, '-');
335 valueStr.insert(18, 1, '-');
336 valueStr.insert(23, 1, '-');
337 }
338 BMCWEB_LOG_DEBUG("UUID = {}", valueStr);
339 asyncResp->res.jsonValue["UUID"] = valueStr;
340 }
341}
342
343inline void
344 afterGetInventory(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
345 const boost::system::error_code& ec,
346 const dbus::utility::DBusPropertiesMap& propertiesList)
347{
348 if (ec)
349 {
350 // doesn't have to include this
351 // interface
352 return;
353 }
354 BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
355
356 const std::string* partNumber = nullptr;
357 const std::string* serialNumber = nullptr;
358 const std::string* manufacturer = nullptr;
359 const std::string* model = nullptr;
360 const std::string* subModel = nullptr;
361
362 const bool success = sdbusplus::unpackPropertiesNoThrow(
363 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
364 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
365 "Model", model, "SubModel", subModel);
366
367 if (!success)
368 {
369 messages::internalError(asyncResp->res);
370 return;
371 }
372
373 if (partNumber != nullptr)
374 {
375 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
376 }
377
378 if (serialNumber != nullptr)
379 {
380 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
381 }
382
383 if (manufacturer != nullptr)
384 {
385 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
386 }
387
388 if (model != nullptr)
389 {
390 asyncResp->res.jsonValue["Model"] = *model;
391 }
392
393 if (subModel != nullptr)
394 {
395 asyncResp->res.jsonValue["SubModel"] = *subModel;
396 }
397
398 // Grab the bios version
399 sw_util::populateSoftwareInformation(asyncResp, sw_util::biosPurpose,
400 "BiosVersion", false);
401}
402
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400403inline void afterGetAssetTag(
404 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
405 const boost::system::error_code& ec, const std::string& value)
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500406{
407 if (ec)
408 {
409 // doesn't have to include this
410 // interface
411 return;
412 }
413
414 asyncResp->res.jsonValue["AssetTag"] = value;
415}
416
417inline void afterSystemGetSubTree(
418 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500419 const boost::system::error_code& ec,
420 const dbus::utility::MapperGetSubTreeResponse& subtree)
421{
422 if (ec)
423 {
424 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
425 messages::internalError(asyncResp->res);
426 return;
427 }
428 // Iterate over all retrieved ObjectPaths.
429 for (const std::pair<
430 std::string,
431 std::vector<std::pair<std::string, std::vector<std::string>>>>&
432 object : subtree)
433 {
434 const std::string& path = object.first;
435 BMCWEB_LOG_DEBUG("Got path: {}", path);
436 const std::vector<std::pair<std::string, std::vector<std::string>>>&
437 connectionNames = object.second;
438 if (connectionNames.empty())
439 {
440 continue;
441 }
442
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500443 // This is not system, so check if it's cpu, dimm, UUID or
444 // BiosVer
445 for (const auto& connection : connectionNames)
446 {
447 for (const auto& interfaceName : connection.second)
448 {
449 if (interfaceName == "xyz.openbmc_project.Inventory.Item.Dimm")
450 {
451 BMCWEB_LOG_DEBUG("Found Dimm, now get its properties.");
452
453 getMemorySummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500454 }
455 else if (interfaceName ==
456 "xyz.openbmc_project.Inventory.Item.Cpu")
457 {
458 BMCWEB_LOG_DEBUG("Found Cpu, now get its properties.");
459
460 getProcessorSummary(asyncResp, connection.first, path);
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500461 }
462 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
463 {
464 BMCWEB_LOG_DEBUG("Found UUID, now get its properties.");
465
Ed Tanousdeae6a72024-11-11 21:58:57 -0800466 dbus::utility::getAllProperties(
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500467 *crow::connections::systemBus, connection.first, path,
468 "xyz.openbmc_project.Common.UUID",
469 [asyncResp](const boost::system::error_code& ec3,
470 const dbus::utility::DBusPropertiesMap&
471 properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400472 afterGetUUID(asyncResp, ec3, properties);
473 });
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500474 }
475 else if (interfaceName ==
476 "xyz.openbmc_project.Inventory.Item.System")
477 {
Ed Tanousdeae6a72024-11-11 21:58:57 -0800478 dbus::utility::getAllProperties(
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500479 *crow::connections::systemBus, connection.first, path,
480 "xyz.openbmc_project.Inventory.Decorator.Asset",
481 [asyncResp](const boost::system::error_code& ec3,
482 const dbus::utility::DBusPropertiesMap&
483 properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400484 afterGetInventory(asyncResp, ec3, properties);
485 });
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500486
Ed Tanousdeae6a72024-11-11 21:58:57 -0800487 dbus::utility::getProperty<std::string>(
488 connection.first, path,
Lakshmi Yadlapatia974c132023-10-25 15:31:25 -0500489 "xyz.openbmc_project.Inventory.Decorator."
490 "AssetTag",
491 "AssetTag",
492 std::bind_front(afterGetAssetTag, asyncResp));
493 }
494 }
495 }
496 }
497}
498
Ninad Palsulecf0e0042023-05-18 17:18:09 -0500499/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700500 * @brief Retrieves computer system properties over dbus
501 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700502 * @param[in] asyncResp Shared pointer for completing asynchronous calls
Ed Tanous6c34de42018-08-29 13:37:36 -0700503 *
504 * @return None.
505 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700506inline void
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500507 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700508{
Ed Tanous62598e32023-07-17 17:06:25 -0700509 BMCWEB_LOG_DEBUG("Get available system components.");
George Liue99073f2022-12-09 11:06:16 +0800510 constexpr std::array<std::string_view, 5> interfaces = {
511 "xyz.openbmc_project.Inventory.Decorator.Asset",
512 "xyz.openbmc_project.Inventory.Item.Cpu",
513 "xyz.openbmc_project.Inventory.Item.Dimm",
514 "xyz.openbmc_project.Inventory.Item.System",
515 "xyz.openbmc_project.Common.UUID",
516 };
517 dbus::utility::getSubTree(
518 "/xyz/openbmc_project/inventory", 0, interfaces,
Gunnar Mills51bd2d82024-04-01 15:25:51 -0500519 std::bind_front(afterSystemGetSubTree, asyncResp));
Ed Tanous6c34de42018-08-29 13:37:36 -0700520}
521
522/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700523 * @brief Retrieves host state properties over dbus
524 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700525 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Ed Tanous6c34de42018-08-29 13:37:36 -0700526 *
527 * @return None.
528 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700529inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700530{
Ed Tanous62598e32023-07-17 17:06:25 -0700531 BMCWEB_LOG_DEBUG("Get host information.");
Ed Tanousdeae6a72024-11-11 21:58:57 -0800532 dbus::utility::getProperty<std::string>(
533 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
534 "xyz.openbmc_project.State.Host", "CurrentHostState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700535 [asyncResp](const boost::system::error_code& ec,
536 const std::string& hostState) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400537 if (ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700538 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400539 if (ec == boost::system::errc::host_unreachable)
540 {
541 // Service not available, no error, just don't return
542 // host state info
543 BMCWEB_LOG_DEBUG("Service not available {}", ec);
544 return;
545 }
546 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
547 messages::internalError(asyncResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700548 return;
549 }
Ed Tanous66173382018-08-15 18:20:59 -0700550
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400551 BMCWEB_LOG_DEBUG("Host state: {}", hostState);
552 // Verify Host State
553 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
554 {
555 asyncResp->res.jsonValue["PowerState"] =
556 resource::PowerState::On;
557 asyncResp->res.jsonValue["Status"]["State"] =
558 resource::State::Enabled;
559 }
560 else if (hostState ==
561 "xyz.openbmc_project.State.Host.HostState.Quiesced")
562 {
563 asyncResp->res.jsonValue["PowerState"] =
564 resource::PowerState::On;
565 asyncResp->res.jsonValue["Status"]["State"] =
566 resource::State::Quiesced;
567 }
568 else if (hostState ==
569 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
570 {
571 asyncResp->res.jsonValue["PowerState"] =
572 resource::PowerState::On;
573 asyncResp->res.jsonValue["Status"]["State"] =
574 resource::State::InTest;
575 }
576 else if (
577 hostState ==
578 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
579 {
580 asyncResp->res.jsonValue["PowerState"] =
581 resource::PowerState::PoweringOn;
582 asyncResp->res.jsonValue["Status"]["State"] =
583 resource::State::Starting;
584 }
585 else if (
586 hostState ==
587 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
588 {
589 asyncResp->res.jsonValue["PowerState"] =
590 resource::PowerState::PoweringOff;
591 asyncResp->res.jsonValue["Status"]["State"] =
592 resource::State::Disabled;
593 }
594 else
595 {
596 asyncResp->res.jsonValue["PowerState"] =
597 resource::PowerState::Off;
598 asyncResp->res.jsonValue["Status"]["State"] =
599 resource::State::Disabled;
600 }
601 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700602}
603
604/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500605 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530606 *
607 * @param[in] dbusSource The boot source in DBUS speak.
608 *
609 * @return Returns as a string, the boot source in Redfish terms. If translation
610 * cannot be done, returns an empty string.
611 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000612inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530613{
614 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
615 {
616 return "None";
617 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700618 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530619 {
620 return "Hdd";
621 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700622 if (dbusSource ==
623 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530624 {
625 return "Cd";
626 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700627 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530628 {
629 return "Pxe";
630 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700631 if (dbusSource ==
632 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700633 {
634 return "Usb";
635 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700636 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530637}
638
639/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300640 * @brief Translates boot type DBUS property value to redfish.
641 *
642 * @param[in] dbusType The boot type in DBUS speak.
643 *
644 * @return Returns as a string, the boot type in Redfish terms. If translation
645 * cannot be done, returns an empty string.
646 */
647inline std::string dbusToRfBootType(const std::string& dbusType)
648{
649 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
650 {
651 return "Legacy";
652 }
653 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
654 {
655 return "UEFI";
656 }
657 return "";
658}
659
660/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500661 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530662 *
663 * @param[in] dbusMode The boot mode in DBUS speak.
664 *
665 * @return Returns as a string, the boot mode in Redfish terms. If translation
666 * cannot be done, returns an empty string.
667 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000668inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530669{
670 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
671 {
672 return "None";
673 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700674 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530675 {
676 return "Diags";
677 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700678 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530679 {
680 return "BiosSetup";
681 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700682 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530683}
684
685/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600686 * @brief Translates boot progress DBUS property value to redfish.
687 *
688 * @param[in] dbusBootProgress The boot progress in DBUS speak.
689 *
690 * @return Returns as a string, the boot progress in Redfish terms. If
691 * translation cannot be done, returns "None".
692 */
693inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
694{
695 // Now convert the D-Bus BootProgress to the appropriate Redfish
696 // enum
697 std::string rfBpLastState = "None";
698 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
699 "ProgressStages.Unspecified")
700 {
701 rfBpLastState = "None";
702 }
703 else if (dbusBootProgress ==
704 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
705 "PrimaryProcInit")
706 {
707 rfBpLastState = "PrimaryProcessorInitializationStarted";
708 }
709 else if (dbusBootProgress ==
710 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
711 "BusInit")
712 {
713 rfBpLastState = "BusInitializationStarted";
714 }
715 else if (dbusBootProgress ==
716 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
717 "MemoryInit")
718 {
719 rfBpLastState = "MemoryInitializationStarted";
720 }
721 else if (dbusBootProgress ==
722 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
723 "SecondaryProcInit")
724 {
725 rfBpLastState = "SecondaryProcessorInitializationStarted";
726 }
727 else if (dbusBootProgress ==
728 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
729 "PCIInit")
730 {
731 rfBpLastState = "PCIResourceConfigStarted";
732 }
733 else if (dbusBootProgress ==
734 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
735 "SystemSetup")
736 {
737 rfBpLastState = "SetupEntered";
738 }
739 else if (dbusBootProgress ==
740 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
741 "SystemInitComplete")
742 {
743 rfBpLastState = "SystemHardwareInitializationComplete";
744 }
745 else if (dbusBootProgress ==
746 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
747 "OSStart")
748 {
749 rfBpLastState = "OSBootStarted";
750 }
751 else if (dbusBootProgress ==
752 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
753 "OSRunning")
754 {
755 rfBpLastState = "OSRunning";
756 }
757 else
758 {
Ed Tanous62598e32023-07-17 17:06:25 -0700759 BMCWEB_LOG_DEBUG("Unsupported D-Bus BootProgress {}", dbusBootProgress);
Andrew Geisslere43914b2022-01-06 13:59:39 -0600760 // Just return the default
761 }
762 return rfBpLastState;
763}
764
765/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500766 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530767 *
768 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700769 * @param[out] bootSource The DBus source
770 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530771 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700772 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530773 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400774inline int assignBootParameters(
775 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
776 const std::string& rfSource, std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530777{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300778 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
779 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700780
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530781 if (rfSource == "None")
782 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700783 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530784 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700785 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530786 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700787 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
788 }
789 else if (rfSource == "Hdd")
790 {
791 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
792 }
793 else if (rfSource == "Diags")
794 {
795 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
796 }
797 else if (rfSource == "Cd")
798 {
799 bootSource =
800 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
801 }
802 else if (rfSource == "BiosSetup")
803 {
804 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530805 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700806 else if (rfSource == "Usb")
807 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700808 bootSource =
809 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700810 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530811 else
812 {
Ed Tanous62598e32023-07-17 17:06:25 -0700813 BMCWEB_LOG_DEBUG(
814 "Invalid property value for BootSourceOverrideTarget: {}",
815 bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -0700816 messages::propertyValueNotInList(asyncResp->res, rfSource,
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700817 "BootSourceTargetOverride");
818 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530819 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700820 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530821}
Ali Ahmed19817712021-06-29 17:01:52 -0500822
Andrew Geissler978b8802020-11-19 13:36:40 -0600823/**
824 * @brief Retrieves boot progress of the system
825 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700826 * @param[in] asyncResp Shared pointer for generating response message.
Andrew Geissler978b8802020-11-19 13:36:40 -0600827 *
828 * @return None.
829 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700830inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600831{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800832 dbus::utility::getProperty<std::string>(
833 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700834 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanousac106bf2023-06-07 09:24:59 -0700835 [asyncResp](const boost::system::error_code& ec,
836 const std::string& bootProgressStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400837 if (ec)
838 {
839 // BootProgress is an optional object so just do nothing if
840 // not found
841 return;
842 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600843
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400844 BMCWEB_LOG_DEBUG("Boot Progress: {}", bootProgressStr);
Andrew Geissler978b8802020-11-19 13:36:40 -0600845
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400846 asyncResp->res.jsonValue["BootProgress"]["LastState"] =
847 dbusToRfBootProgress(bootProgressStr);
848 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600849}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530850
851/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000852 * @brief Retrieves boot progress Last Update of the system
853 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700854 * @param[in] asyncResp Shared pointer for generating response message.
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000855 *
856 * @return None.
857 */
858inline void getBootProgressLastStateTime(
Ed Tanousac106bf2023-06-07 09:24:59 -0700859 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000860{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800861 dbus::utility::getProperty<uint64_t>(
862 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000863 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanousac106bf2023-06-07 09:24:59 -0700864 [asyncResp](const boost::system::error_code& ec,
865 const uint64_t lastStateTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400866 if (ec)
867 {
868 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
869 return;
870 }
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000871
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400872 // BootProgressLastUpdate is the last time the BootProgress property
873 // was updated. The time is the Epoch time, number of microseconds
874 // since 1 Jan 1970 00::00::00 UTC."
875 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
876 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000877
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400878 // Convert to ISO 8601 standard
879 asyncResp->res.jsonValue["BootProgress"]["LastStateTime"] =
880 redfish::time_utils::getDateTimeUintUs(lastStateTime);
881 });
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000882}
883
884/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300885 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300886 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700887 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300888 *
889 * @return None.
890 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300891
Ed Tanousac106bf2023-06-07 09:24:59 -0700892inline void
893 getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300894{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800895 dbus::utility::getProperty<std::string>(
896 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700897 "/xyz/openbmc_project/control/host0/boot",
898 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanousac106bf2023-06-07 09:24:59 -0700899 [asyncResp](const boost::system::error_code& ec,
900 const std::string& bootType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400901 if (ec)
902 {
903 // not an error, don't have to have the interface
904 return;
905 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300906
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400907 BMCWEB_LOG_DEBUG("Boot type: {}", bootType);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300908
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400909 asyncResp->res
910 .jsonValue["Boot"]
911 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
912 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300913
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400914 auto rfType = dbusToRfBootType(bootType);
915 if (rfType.empty())
916 {
917 messages::internalError(asyncResp->res);
918 return;
919 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300920
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400921 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
922 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300923}
924
925/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300926 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530927 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700928 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530929 *
930 * @return None.
931 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300932
Ed Tanousac106bf2023-06-07 09:24:59 -0700933inline void
934 getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530935{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800936 dbus::utility::getProperty<std::string>(
937 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700938 "/xyz/openbmc_project/control/host0/boot",
939 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700940 [asyncResp](const boost::system::error_code& ec,
941 const std::string& bootModeStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400942 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530943 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400944 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
945 messages::internalError(asyncResp->res);
946 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530947 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400948
949 BMCWEB_LOG_DEBUG("Boot mode: {}", bootModeStr);
950
951 nlohmann::json::array_t allowed;
952 allowed.emplace_back("None");
953 allowed.emplace_back("Pxe");
954 allowed.emplace_back("Hdd");
955 allowed.emplace_back("Cd");
956 allowed.emplace_back("Diags");
957 allowed.emplace_back("BiosSetup");
958 allowed.emplace_back("Usb");
959
960 asyncResp->res
961 .jsonValue["Boot"]
962 ["BootSourceOverrideTarget@Redfish.AllowableValues"] =
963 std::move(allowed);
964 if (bootModeStr !=
965 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
966 {
967 auto rfMode = dbusToRfBootMode(bootModeStr);
968 if (!rfMode.empty())
969 {
970 asyncResp->res
971 .jsonValue["Boot"]["BootSourceOverrideTarget"] = rfMode;
972 }
973 }
974 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530975}
976
977/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300978 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530979 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700980 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530981 *
982 * @return None.
983 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300984
985inline void
Ed Tanousac106bf2023-06-07 09:24:59 -0700986 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530987{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800988 dbus::utility::getProperty<std::string>(
989 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700990 "/xyz/openbmc_project/control/host0/boot",
991 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanousac106bf2023-06-07 09:24:59 -0700992 [asyncResp](const boost::system::error_code& ec,
993 const std::string& bootSourceStr) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400994 if (ec)
Nan Zhou5ef735c2022-06-22 05:24:21 +0000995 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400996 if (ec.value() == boost::asio::error::host_unreachable)
997 {
998 return;
999 }
1000 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1001 messages::internalError(asyncResp->res);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001002 return;
1003 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301004
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001005 BMCWEB_LOG_DEBUG("Boot source: {}", bootSourceStr);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301006
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001007 auto rfSource = dbusToRfBootSource(bootSourceStr);
1008 if (!rfSource.empty())
1009 {
1010 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
1011 rfSource;
1012 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001013
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001014 // Get BootMode as BootSourceOverrideTarget is constructed
1015 // from both BootSource and BootMode
1016 getBootOverrideMode(asyncResp);
1017 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301018}
1019
1020/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001021 * @brief This functions abstracts all the logic behind getting a
1022 * "BootSourceOverrideEnabled" property from an overall boot override enable
1023 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001025 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301026 *
1027 * @return None.
1028 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301029
Ed Tanousac106bf2023-06-07 09:24:59 -07001030inline void processBootOverrideEnable(
1031 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1032 const bool bootOverrideEnableSetting)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001033{
1034 if (!bootOverrideEnableSetting)
1035 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001036 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1037 "Disabled";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001038 return;
1039 }
1040
1041 // If boot source override is enabled, we need to check 'one_time'
1042 // property to set a correct value for the "BootSourceOverrideEnabled"
Ed Tanousdeae6a72024-11-11 21:58:57 -08001043 dbus::utility::getProperty<bool>(
1044 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001045 "/xyz/openbmc_project/control/host0/boot/one_time",
1046 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001047 [asyncResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001048 if (ec)
1049 {
1050 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1051 messages::internalError(asyncResp->res);
1052 return;
1053 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301054
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001055 if (oneTimeSetting)
1056 {
1057 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1058 "Once";
1059 }
1060 else
1061 {
1062 asyncResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1063 "Continuous";
1064 }
1065 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301066}
1067
1068/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001069 * @brief Retrieves boot override enable over DBUS
1070 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001071 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001072 *
1073 * @return None.
1074 */
1075
1076inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001077 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001078{
Ed Tanousdeae6a72024-11-11 21:58:57 -08001079 dbus::utility::getProperty<bool>(
1080 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001081 "/xyz/openbmc_project/control/host0/boot",
1082 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanousac106bf2023-06-07 09:24:59 -07001083 [asyncResp](const boost::system::error_code& ec,
1084 const bool bootOverrideEnable) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001085 if (ec)
Nan Zhou5ef735c2022-06-22 05:24:21 +00001086 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001087 if (ec.value() == boost::asio::error::host_unreachable)
1088 {
1089 return;
1090 }
1091 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1092 messages::internalError(asyncResp->res);
Nan Zhou5ef735c2022-06-22 05:24:21 +00001093 return;
1094 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001095
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001096 processBootOverrideEnable(asyncResp, bootOverrideEnable);
1097 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001098}
1099
1100/**
1101 * @brief Retrieves boot source override properties
1102 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001103 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001104 *
1105 * @return None.
1106 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001107inline void
1108 getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001109{
Ed Tanous62598e32023-07-17 17:06:25 -07001110 BMCWEB_LOG_DEBUG("Get boot information.");
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001111
Ed Tanousac106bf2023-06-07 09:24:59 -07001112 getBootOverrideSource(asyncResp);
1113 getBootOverrideType(asyncResp);
1114 getBootOverrideEnable(asyncResp);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001115}
1116
1117/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001118 * @brief Retrieves the Last Reset Time
1119 *
1120 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1121 * and power off. Even though this is the "system" Redfish object look at the
1122 * chassis D-Bus interface for the LastStateChangeTime since this has the
1123 * last power operation time.
1124 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001125 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Millsc0557e12020-06-30 11:26:20 -05001126 *
1127 * @return None.
1128 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001129inline void
1130 getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001131{
Ed Tanous62598e32023-07-17 17:06:25 -07001132 BMCWEB_LOG_DEBUG("Getting System Last Reset Time");
Gunnar Millsc0557e12020-06-30 11:26:20 -05001133
Ed Tanousdeae6a72024-11-11 21:58:57 -08001134 dbus::utility::getProperty<uint64_t>(
1135 "xyz.openbmc_project.State.Chassis",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001136 "/xyz/openbmc_project/state/chassis0",
1137 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanousac106bf2023-06-07 09:24:59 -07001138 [asyncResp](const boost::system::error_code& ec,
1139 uint64_t lastResetTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001140 if (ec)
1141 {
1142 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
1143 return;
1144 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001145
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001146 // LastStateChangeTime is epoch time, in milliseconds
1147 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1148 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001149
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001150 // Convert to ISO 8601 standard
1151 asyncResp->res.jsonValue["LastResetTime"] =
1152 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
1153 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001154}
1155
1156/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001157 * @brief Retrieves the number of automatic boot Retry attempts allowed/left.
1158 *
1159 * The total number of automatic reboot retries allowed "RetryAttempts" and its
1160 * corresponding property "AttemptsLeft" that keeps track of the amount of
1161 * automatic retry attempts left are hosted in phosphor-state-manager through
1162 * dbus.
1163 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001164 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001165 *
1166 * @return None.
1167 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001168inline void getAutomaticRebootAttempts(
1169 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001170{
Ed Tanous62598e32023-07-17 17:06:25 -07001171 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Corey Hardesty797d5da2022-04-26 17:54:52 +08001172
Ed Tanousdeae6a72024-11-11 21:58:57 -08001173 dbus::utility::getAllProperties(
1174 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Corey Hardesty797d5da2022-04-26 17:54:52 +08001175 "xyz.openbmc_project.Control.Boot.RebootAttempts",
Ed Tanousac106bf2023-06-07 09:24:59 -07001176 [asyncResp{asyncResp}](
1177 const boost::system::error_code& ec,
1178 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001179 if (ec)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001180 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001181 if (ec.value() != EBADR)
1182 {
1183 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1184 messages::internalError(asyncResp->res);
1185 }
1186 return;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001187 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001188
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001189 const uint32_t* attemptsLeft = nullptr;
1190 const uint32_t* retryAttempts = nullptr;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001191
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001192 const bool success = sdbusplus::unpackPropertiesNoThrow(
1193 dbus_utils::UnpackErrorPrinter(), propertiesList,
1194 "AttemptsLeft", attemptsLeft, "RetryAttempts", retryAttempts);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001195
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001196 if (!success)
1197 {
1198 messages::internalError(asyncResp->res);
1199 return;
1200 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001201
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001202 if (attemptsLeft != nullptr)
1203 {
1204 asyncResp->res
1205 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1206 *attemptsLeft;
1207 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08001208
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001209 if (retryAttempts != nullptr)
1210 {
1211 asyncResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] =
1212 *retryAttempts;
1213 }
1214 });
Corey Hardesty797d5da2022-04-26 17:54:52 +08001215}
1216
1217/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001218 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1219 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001220 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001221 *
1222 * @return None.
1223 */
Corey Hardesty797d5da2022-04-26 17:54:52 +08001224inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001225 getAutomaticRetryPolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001226{
Ed Tanous62598e32023-07-17 17:06:25 -07001227 BMCWEB_LOG_DEBUG("Get Automatic Retry policy");
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001228
Ed Tanousdeae6a72024-11-11 21:58:57 -08001229 dbus::utility::getProperty<bool>(
1230 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001231 "/xyz/openbmc_project/control/host0/auto_reboot",
1232 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanousac106bf2023-06-07 09:24:59 -07001233 [asyncResp](const boost::system::error_code& ec,
1234 bool autoRebootEnabled) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001235 if (ec)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001236 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001237 if (ec.value() != EBADR)
1238 {
1239 BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec);
1240 messages::internalError(asyncResp->res);
1241 }
1242 return;
Corey Hardesty797d5da2022-04-26 17:54:52 +08001243 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001244
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001245 BMCWEB_LOG_DEBUG("Auto Reboot: {}", autoRebootEnabled);
1246 if (autoRebootEnabled)
1247 {
1248 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1249 "RetryAttempts";
1250 }
1251 else
1252 {
1253 asyncResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1254 "Disabled";
1255 }
1256 getAutomaticRebootAttempts(asyncResp);
Gunnar Mills69f35302020-05-17 16:06:31 -05001257
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001258 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1259 // and RetryAttempts. OpenBMC only supports Disabled and
1260 // RetryAttempts.
1261 nlohmann::json::array_t allowed;
1262 allowed.emplace_back("Disabled");
1263 allowed.emplace_back("RetryAttempts");
1264 asyncResp->res
1265 .jsonValue["Boot"]
1266 ["AutomaticRetryConfig@Redfish.AllowableValues"] =
1267 std::move(allowed);
1268 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001269}
1270
1271/**
Corey Hardesty797d5da2022-04-26 17:54:52 +08001272 * @brief Sets RetryAttempts
1273 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001274 * @param[in] asyncResp Shared pointer for generating response message.
Corey Hardesty797d5da2022-04-26 17:54:52 +08001275 * @param[in] retryAttempts "AutomaticRetryAttempts" from request.
1276 *
1277 *@return None.
1278 */
1279
Ed Tanousac106bf2023-06-07 09:24:59 -07001280inline void setAutomaticRetryAttempts(
1281 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1282 const uint32_t retryAttempts)
Corey Hardesty797d5da2022-04-26 17:54:52 +08001283{
Ed Tanous62598e32023-07-17 17:06:25 -07001284 BMCWEB_LOG_DEBUG("Set Automatic Retry Attempts.");
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001285 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301286 asyncResp, "Boot/AutomaticRetryAttempts",
1287 "xyz.openbmc_project.State.Host",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001288 sdbusplus::message::object_path("/xyz/openbmc_project/state/host0"),
Corey Hardesty797d5da2022-04-26 17:54:52 +08001289 "xyz.openbmc_project.Control.Boot.RebootAttempts", "RetryAttempts",
Ginu Georgee93abac2024-06-14 17:35:27 +05301290 retryAttempts);
Corey Hardesty797d5da2022-04-26 17:54:52 +08001291}
1292
Ed Tanous8d69c662023-06-21 10:29:06 -07001293inline computer_system::PowerRestorePolicyTypes
1294 redfishPowerRestorePolicyFromDbus(std::string_view value)
1295{
1296 if (value ==
1297 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn")
1298 {
1299 return computer_system::PowerRestorePolicyTypes::AlwaysOn;
1300 }
1301 if (value ==
1302 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff")
1303 {
1304 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1305 }
1306 if (value ==
Gunnar Mills3a34b742023-07-28 10:17:14 -05001307 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore")
Ed Tanous8d69c662023-06-21 10:29:06 -07001308 {
1309 return computer_system::PowerRestorePolicyTypes::LastState;
1310 }
1311 if (value == "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None")
1312 {
1313 return computer_system::PowerRestorePolicyTypes::AlwaysOff;
1314 }
1315 return computer_system::PowerRestorePolicyTypes::Invalid;
1316}
Corey Hardesty797d5da2022-04-26 17:54:52 +08001317/**
George Liuc6a620f2020-04-10 17:18:11 +08001318 * @brief Retrieves power restore policy over DBUS.
1319 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001320 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001321 *
1322 * @return None.
1323 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001324inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001325 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
George Liuc6a620f2020-04-10 17:18:11 +08001326{
Ed Tanous62598e32023-07-17 17:06:25 -07001327 BMCWEB_LOG_DEBUG("Get power restore policy");
George Liuc6a620f2020-04-10 17:18:11 +08001328
Ed Tanousdeae6a72024-11-11 21:58:57 -08001329 dbus::utility::getProperty<std::string>(
1330 "xyz.openbmc_project.Settings",
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001331 "/xyz/openbmc_project/control/host0/power_restore_policy",
1332 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanousac106bf2023-06-07 09:24:59 -07001333 [asyncResp](const boost::system::error_code& ec,
1334 const std::string& policy) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001335 if (ec)
1336 {
1337 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1338 return;
1339 }
1340 computer_system::PowerRestorePolicyTypes restore =
1341 redfishPowerRestorePolicyFromDbus(policy);
1342 if (restore == computer_system::PowerRestorePolicyTypes::Invalid)
1343 {
1344 messages::internalError(asyncResp->res);
1345 return;
1346 }
George Liuc6a620f2020-04-10 17:18:11 +08001347
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001348 asyncResp->res.jsonValue["PowerRestorePolicy"] = restore;
1349 });
George Liuc6a620f2020-04-10 17:18:11 +08001350}
1351
1352/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001353 * @brief Stop Boot On Fault over DBUS.
1354 *
1355 * @param[in] asyncResp Shared pointer for generating response message.
1356 *
1357 * @return None.
1358 */
1359inline void
1360 getStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1361{
Ed Tanous62598e32023-07-17 17:06:25 -07001362 BMCWEB_LOG_DEBUG("Get Stop Boot On Fault");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001363
Ed Tanousdeae6a72024-11-11 21:58:57 -08001364 dbus::utility::getProperty<bool>(
1365 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/logging/settings",
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001366 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
1367 [asyncResp](const boost::system::error_code& ec, bool value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001368 if (ec)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001369 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001370 if (ec.value() != EBADR)
1371 {
1372 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
1373 messages::internalError(asyncResp->res);
1374 }
1375 return;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001376 }
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001377
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001378 if (value)
1379 {
1380 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1381 computer_system::StopBootOnFault::AnyFault;
1382 }
1383 else
1384 {
1385 asyncResp->res.jsonValue["Boot"]["StopBootOnFault"] =
1386 computer_system::StopBootOnFault::Never;
1387 }
1388 });
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001389}
1390
1391/**
Ali Ahmed19817712021-06-29 17:01:52 -05001392 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1393 * TPM is required for booting the host.
1394 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001395 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed19817712021-06-29 17:01:52 -05001396 *
1397 * @return None.
1398 */
1399inline void getTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001400 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ali Ahmed19817712021-06-29 17:01:52 -05001401{
Ed Tanous62598e32023-07-17 17:06:25 -07001402 BMCWEB_LOG_DEBUG("Get TPM required to boot.");
George Liue99073f2022-12-09 11:06:16 +08001403 constexpr std::array<std::string_view, 1> interfaces = {
1404 "xyz.openbmc_project.Control.TPM.Policy"};
1405 dbus::utility::getSubTree(
1406 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001407 [asyncResp](const boost::system::error_code& ec,
1408 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001409 if (ec)
Ali Ahmed19817712021-06-29 17:01:52 -05001410 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001411 BMCWEB_LOG_DEBUG(
1412 "DBUS response error on TPM.Policy GetSubTree{}", ec);
1413 // This is an optional D-Bus object so just return if
1414 // error occurs
1415 return;
1416 }
1417 if (subtree.empty())
1418 {
1419 // As noted above, this is an optional interface so just return
1420 // if there is no instance found
1421 return;
1422 }
1423
1424 /* When there is more than one TPMEnable object... */
1425 if (subtree.size() > 1)
1426 {
1427 BMCWEB_LOG_DEBUG(
1428 "DBUS response has more than 1 TPM Enable object:{}",
1429 subtree.size());
1430 // Throw an internal Error and return
Ed Tanousac106bf2023-06-07 09:24:59 -07001431 messages::internalError(asyncResp->res);
Ali Ahmed19817712021-06-29 17:01:52 -05001432 return;
1433 }
1434
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001435 // Make sure the Dbus response map has a service and objectPath
1436 // field
1437 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
Ali Ahmed19817712021-06-29 17:01:52 -05001438 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001439 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1440 messages::internalError(asyncResp->res);
1441 return;
Ali Ahmed19817712021-06-29 17:01:52 -05001442 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001443
1444 const std::string& path = subtree[0].first;
1445 const std::string& serv = subtree[0].second.begin()->first;
1446
1447 // Valid TPM Enable object found, now reading the current value
Ed Tanousdeae6a72024-11-11 21:58:57 -08001448 dbus::utility::getProperty<bool>(
1449 serv, path, "xyz.openbmc_project.Control.TPM.Policy",
1450 "TPMEnable",
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001451 [asyncResp](const boost::system::error_code& ec2,
1452 bool tpmRequired) {
1453 if (ec2)
1454 {
1455 BMCWEB_LOG_ERROR(
1456 "D-BUS response error on TPM.Policy Get{}", ec2);
1457 messages::internalError(asyncResp->res);
1458 return;
1459 }
1460
1461 if (tpmRequired)
1462 {
1463 asyncResp->res
1464 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1465 "Required";
1466 }
1467 else
1468 {
1469 asyncResp->res
1470 .jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1471 "Disabled";
1472 }
1473 });
George Liue99073f2022-12-09 11:06:16 +08001474 });
Ali Ahmed19817712021-06-29 17:01:52 -05001475}
1476
1477/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001478 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1479 * TPM is required for booting the host.
1480 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001481 * @param[in] asyncResp Shared pointer for generating response message.
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001482 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1483 *
1484 * @return None.
1485 */
1486inline void setTrustedModuleRequiredToBoot(
Ed Tanousac106bf2023-06-07 09:24:59 -07001487 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const bool tpmRequired)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001488{
Ed Tanous62598e32023-07-17 17:06:25 -07001489 BMCWEB_LOG_DEBUG("Set TrustedModuleRequiredToBoot.");
George Liue99073f2022-12-09 11:06:16 +08001490 constexpr std::array<std::string_view, 1> interfaces = {
1491 "xyz.openbmc_project.Control.TPM.Policy"};
1492 dbus::utility::getSubTree(
1493 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001494 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001495 tpmRequired](const boost::system::error_code& ec,
1496 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001497 if (ec)
1498 {
1499 BMCWEB_LOG_ERROR(
1500 "DBUS response error on TPM.Policy GetSubTree{}", ec);
1501 messages::internalError(asyncResp->res);
1502 return;
1503 }
1504 if (subtree.empty())
1505 {
1506 messages::propertyValueNotInList(asyncResp->res,
1507 "ComputerSystem",
1508 "TrustedModuleRequiredToBoot");
1509 return;
1510 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001511
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001512 /* When there is more than one TPMEnable object... */
1513 if (subtree.size() > 1)
1514 {
1515 BMCWEB_LOG_DEBUG(
1516 "DBUS response has more than 1 TPM Enable object:{}",
1517 subtree.size());
1518 // Throw an internal Error and return
1519 messages::internalError(asyncResp->res);
1520 return;
1521 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001522
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001523 // Make sure the Dbus response map has a service and objectPath
1524 // field
1525 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1526 {
1527 BMCWEB_LOG_DEBUG("TPM.Policy mapper error!");
1528 messages::internalError(asyncResp->res);
1529 return;
1530 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001531
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001532 const std::string& path = subtree[0].first;
1533 const std::string& serv = subtree[0].second.begin()->first;
Ed Tanous002d39b2022-05-31 08:59:27 -07001534
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001535 if (serv.empty())
1536 {
1537 BMCWEB_LOG_DEBUG("TPM.Policy service mapper error!");
1538 messages::internalError(asyncResp->res);
1539 return;
1540 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001541
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001542 // Valid TPM Enable object found, now setting the value
1543 setDbusProperty(asyncResp, "Boot/TrustedModuleRequiredToBoot", serv,
1544 path, "xyz.openbmc_project.Control.TPM.Policy",
1545 "TPMEnable", tpmRequired);
1546 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001547}
1548
1549/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301550 * @brief Sets boot properties into DBUS object(s).
1551 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001552 * @param[in] asyncResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001553 * @param[in] bootType The boot type to set.
1554 * @return Integer error code.
1555 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001556inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001557 const std::optional<std::string>& bootType)
1558{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001559 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001560
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001561 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001562 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001563 return;
1564 }
1565
1566 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001567 BMCWEB_LOG_DEBUG("Boot type: {}", *bootType);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001568 // Figure out which DBUS interface and property to use
1569 if (*bootType == "Legacy")
1570 {
1571 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1572 }
1573 else if (*bootType == "UEFI")
1574 {
1575 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1576 }
1577 else
1578 {
Ed Tanous62598e32023-07-17 17:06:25 -07001579 BMCWEB_LOG_DEBUG("Invalid property value for "
1580 "BootSourceOverrideMode: {}",
1581 *bootType);
Ed Tanousac106bf2023-06-07 09:24:59 -07001582 messages::propertyValueNotInList(asyncResp->res, *bootType,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001583 "BootSourceOverrideMode");
1584 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001585 }
1586
1587 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001588 BMCWEB_LOG_DEBUG("DBUS boot type: {}", bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001589
Ginu Georgee93abac2024-06-14 17:35:27 +05301590 setDbusProperty(asyncResp, "Boot/BootSourceOverrideMode",
1591 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001592 sdbusplus::message::object_path(
1593 "/xyz/openbmc_project/control/host0/boot"),
1594 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ginu Georgee93abac2024-06-14 17:35:27 +05301595 bootTypeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001596}
1597
1598/**
1599 * @brief Sets boot properties into DBUS object(s).
1600 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001601 * @param[in] asyncResp Shared pointer for generating response
1602 * message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001603 * @param[in] bootType The boot type to set.
1604 * @return Integer error code.
1605 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001606inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001607 const std::optional<std::string>& bootEnable)
1608{
1609 if (!bootEnable)
1610 {
1611 return;
1612 }
1613 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001614 BMCWEB_LOG_DEBUG("Boot enable: {}", *bootEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001615
1616 bool bootOverrideEnable = false;
1617 bool bootOverridePersistent = false;
1618 // Figure out which DBUS interface and property to use
1619 if (*bootEnable == "Disabled")
1620 {
1621 bootOverrideEnable = false;
1622 }
1623 else if (*bootEnable == "Once")
1624 {
1625 bootOverrideEnable = true;
1626 bootOverridePersistent = false;
1627 }
1628 else if (*bootEnable == "Continuous")
1629 {
1630 bootOverrideEnable = true;
1631 bootOverridePersistent = true;
1632 }
1633 else
1634 {
Ed Tanous62598e32023-07-17 17:06:25 -07001635 BMCWEB_LOG_DEBUG(
1636 "Invalid property value for BootSourceOverrideEnabled: {}",
1637 *bootEnable);
Ed Tanousac106bf2023-06-07 09:24:59 -07001638 messages::propertyValueNotInList(asyncResp->res, *bootEnable,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001639 "BootSourceOverrideEnabled");
1640 return;
1641 }
1642
1643 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001644 BMCWEB_LOG_DEBUG("DBUS boot override enable: {}", bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001645
Ginu Georgee93abac2024-06-14 17:35:27 +05301646 setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1647 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001648 sdbusplus::message::object_path(
1649 "/xyz/openbmc_project/control/host0/boot"),
1650 "xyz.openbmc_project.Object.Enable", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05301651 bootOverrideEnable);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001652
1653 if (!bootOverrideEnable)
1654 {
1655 return;
1656 }
1657
1658 // In case boot override is enabled we need to set correct value for the
1659 // 'one_time' enable DBus interface
Ed Tanous62598e32023-07-17 17:06:25 -07001660 BMCWEB_LOG_DEBUG("DBUS boot override persistent: {}",
1661 bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001662
Ginu Georgee93abac2024-06-14 17:35:27 +05301663 setDbusProperty(asyncResp, "Boot/BootSourceOverrideEnabled",
1664 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001665 sdbusplus::message::object_path(
1666 "/xyz/openbmc_project/control/host0/boot/one_time"),
1667 "xyz.openbmc_project.Object.Enable", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05301668 !bootOverridePersistent);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001669}
1670
1671/**
1672 * @brief Sets boot properties into DBUS object(s).
1673 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001674 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301675 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301676 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001677 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301678 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001679inline void
1680 setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1681 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301682{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001683 std::string bootSourceStr;
1684 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001685
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001686 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301687 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001688 return;
1689 }
1690
1691 // Source target specified
Ed Tanous62598e32023-07-17 17:06:25 -07001692 BMCWEB_LOG_DEBUG("Boot source: {}", *bootSource);
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001693 // Figure out which DBUS interface and property to use
Ed Tanousac106bf2023-06-07 09:24:59 -07001694 if (assignBootParameters(asyncResp, *bootSource, bootSourceStr,
1695 bootModeStr) != 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001696 {
Ed Tanous62598e32023-07-17 17:06:25 -07001697 BMCWEB_LOG_DEBUG(
1698 "Invalid property value for BootSourceOverrideTarget: {}",
1699 *bootSource);
Ed Tanousac106bf2023-06-07 09:24:59 -07001700 messages::propertyValueNotInList(asyncResp->res, *bootSource,
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001701 "BootSourceTargetOverride");
1702 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001703 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301704
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001705 // Act on validated parameters
Ed Tanous62598e32023-07-17 17:06:25 -07001706 BMCWEB_LOG_DEBUG("DBUS boot source: {}", bootSourceStr);
1707 BMCWEB_LOG_DEBUG("DBUS boot mode: {}", bootModeStr);
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001708
Ginu Georgee93abac2024-06-14 17:35:27 +05301709 setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1710 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001711 sdbusplus::message::object_path(
1712 "/xyz/openbmc_project/control/host0/boot"),
1713 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ginu Georgee93abac2024-06-14 17:35:27 +05301714 bootSourceStr);
1715 setDbusProperty(asyncResp, "Boot/BootSourceOverrideTarget",
1716 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001717 sdbusplus::message::object_path(
1718 "/xyz/openbmc_project/control/host0/boot"),
1719 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ginu Georgee93abac2024-06-14 17:35:27 +05301720 bootModeStr);
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001721}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001722
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001723/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001724 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301725 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001726 * @param[in] asyncResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301727 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001728 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301729 * @param[in] bootEnable The boot override enable from incoming RF request.
1730 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001731 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301732 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001733
Ed Tanousac106bf2023-06-07 09:24:59 -07001734inline void
1735 setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1736 const std::optional<std::string>& bootSource,
1737 const std::optional<std::string>& bootType,
1738 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301739{
Ed Tanous62598e32023-07-17 17:06:25 -07001740 BMCWEB_LOG_DEBUG("Set boot information.");
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301741
Ed Tanousac106bf2023-06-07 09:24:59 -07001742 setBootModeOrSource(asyncResp, bootSource);
1743 setBootType(asyncResp, bootType);
1744 setBootEnable(asyncResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301745}
1746
George Liuc6a620f2020-04-10 17:18:11 +08001747/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001748 * @brief Sets AssetTag
1749 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001750 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills98e386e2020-10-30 14:58:09 -05001751 * @param[in] assetTag "AssetTag" from request.
1752 *
1753 * @return None.
1754 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001755inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001756 const std::string& assetTag)
1757{
George Liue99073f2022-12-09 11:06:16 +08001758 constexpr std::array<std::string_view, 1> interfaces = {
1759 "xyz.openbmc_project.Inventory.Item.System"};
1760 dbus::utility::getSubTree(
1761 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07001762 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08001763 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001764 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001765 if (ec)
1766 {
1767 BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
1768 messages::internalError(asyncResp->res);
1769 return;
1770 }
1771 if (subtree.empty())
1772 {
1773 BMCWEB_LOG_DEBUG("Can't find system D-Bus object!");
1774 messages::internalError(asyncResp->res);
1775 return;
1776 }
1777 // Assume only 1 system D-Bus object
1778 // Throw an error if there is more than 1
1779 if (subtree.size() > 1)
1780 {
1781 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus object!");
1782 messages::internalError(asyncResp->res);
1783 return;
1784 }
1785 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1786 {
1787 BMCWEB_LOG_DEBUG("Asset Tag Set mapper error!");
1788 messages::internalError(asyncResp->res);
1789 return;
1790 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001791
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001792 const std::string& path = subtree[0].first;
1793 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001794
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001795 if (service.empty())
1796 {
1797 BMCWEB_LOG_DEBUG("Asset Tag Set service mapper error!");
1798 messages::internalError(asyncResp->res);
1799 return;
1800 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001801
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001802 setDbusProperty(asyncResp, "AssetTag", service, path,
1803 "xyz.openbmc_project.Inventory.Decorator.AssetTag",
1804 "AssetTag", assetTag);
1805 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001806}
1807
1808/**
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001809 * @brief Validate the specified stopBootOnFault is valid and return the
1810 * stopBootOnFault name associated with that string
1811 *
1812 * @param[in] stopBootOnFaultString String representing the desired
1813 * stopBootOnFault
1814 *
1815 * @return stopBootOnFault value or empty if incoming value is not valid
1816 */
1817inline std::optional<bool>
1818 validstopBootOnFault(const std::string& stopBootOnFaultString)
1819{
1820 if (stopBootOnFaultString == "AnyFault")
1821 {
1822 return true;
1823 }
1824
1825 if (stopBootOnFaultString == "Never")
1826 {
1827 return false;
1828 }
1829
1830 return std::nullopt;
1831}
1832
1833/**
1834 * @brief Sets stopBootOnFault
1835 *
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001836 * @param[in] asyncResp Shared pointer for generating response message.
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001837 * @param[in] stopBootOnFault "StopBootOnFault" from request.
1838 *
1839 * @return None.
1840 */
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001841inline void
1842 setStopBootOnFault(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1843 const std::string& stopBootOnFault)
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001844{
Ed Tanous62598e32023-07-17 17:06:25 -07001845 BMCWEB_LOG_DEBUG("Set Stop Boot On Fault.");
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001846
1847 std::optional<bool> stopBootEnabled = validstopBootOnFault(stopBootOnFault);
1848 if (!stopBootEnabled)
1849 {
Ed Tanous62598e32023-07-17 17:06:25 -07001850 BMCWEB_LOG_DEBUG("Invalid property value for StopBootOnFault: {}",
1851 stopBootOnFault);
Ed Tanousfc3edfd2023-07-20 12:41:30 -07001852 messages::propertyValueNotInList(asyncResp->res, stopBootOnFault,
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001853 "StopBootOnFault");
1854 return;
1855 }
1856
Ginu Georgee93abac2024-06-14 17:35:27 +05301857 setDbusProperty(asyncResp, "Boot/StopBootOnFault",
1858 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001859 sdbusplus::message::object_path(
1860 "/xyz/openbmc_project/logging/settings"),
1861 "xyz.openbmc_project.Logging.Settings", "QuiesceOnHwError",
Ginu Georgee93abac2024-06-14 17:35:27 +05301862 *stopBootEnabled);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08001863}
1864
1865/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001866 * @brief Sets automaticRetry (Auto Reboot)
1867 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001868 * @param[in] asyncResp Shared pointer for generating response message.
Gunnar Mills69f35302020-05-17 16:06:31 -05001869 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1870 *
1871 * @return None.
1872 */
Ed Tanousac106bf2023-06-07 09:24:59 -07001873inline void
1874 setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1875 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001876{
Ed Tanous62598e32023-07-17 17:06:25 -07001877 BMCWEB_LOG_DEBUG("Set Automatic Retry.");
Gunnar Mills69f35302020-05-17 16:06:31 -05001878
1879 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001880 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001881
1882 if (automaticRetryConfig == "Disabled")
1883 {
1884 autoRebootEnabled = false;
1885 }
1886 else if (automaticRetryConfig == "RetryAttempts")
1887 {
1888 autoRebootEnabled = true;
1889 }
1890 else
1891 {
Ed Tanous62598e32023-07-17 17:06:25 -07001892 BMCWEB_LOG_DEBUG("Invalid property value for AutomaticRetryConfig: {}",
1893 automaticRetryConfig);
Ed Tanousac106bf2023-06-07 09:24:59 -07001894 messages::propertyValueNotInList(asyncResp->res, automaticRetryConfig,
Gunnar Mills69f35302020-05-17 16:06:31 -05001895 "AutomaticRetryConfig");
1896 return;
1897 }
1898
Ginu Georgee93abac2024-06-14 17:35:27 +05301899 setDbusProperty(asyncResp, "Boot/AutomaticRetryConfig",
1900 "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001901 sdbusplus::message::object_path(
1902 "/xyz/openbmc_project/control/host0/auto_reboot"),
1903 "xyz.openbmc_project.Control.Boot.RebootPolicy",
Ginu Georgee93abac2024-06-14 17:35:27 +05301904 "AutoReboot", autoRebootEnabled);
Gunnar Mills69f35302020-05-17 16:06:31 -05001905}
1906
Ed Tanous8d69c662023-06-21 10:29:06 -07001907inline std::string dbusPowerRestorePolicyFromRedfish(std::string_view policy)
1908{
1909 if (policy == "AlwaysOn")
1910 {
1911 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn";
1912 }
1913 if (policy == "AlwaysOff")
1914 {
1915 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff";
1916 }
1917 if (policy == "LastState")
1918 {
1919 return "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore";
1920 }
1921 return "";
1922}
1923
Gunnar Mills69f35302020-05-17 16:06:31 -05001924/**
George Liuc6a620f2020-04-10 17:18:11 +08001925 * @brief Sets power restore policy properties.
1926 *
Ed Tanousac106bf2023-06-07 09:24:59 -07001927 * @param[in] asyncResp Shared pointer for generating response message.
George Liuc6a620f2020-04-10 17:18:11 +08001928 * @param[in] policy power restore policy properties from request.
1929 *
1930 * @return None.
1931 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001932inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07001933 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous8d69c662023-06-21 10:29:06 -07001934 std::string_view policy)
George Liuc6a620f2020-04-10 17:18:11 +08001935{
Ed Tanous62598e32023-07-17 17:06:25 -07001936 BMCWEB_LOG_DEBUG("Set power restore policy.");
George Liuc6a620f2020-04-10 17:18:11 +08001937
Ed Tanous8d69c662023-06-21 10:29:06 -07001938 std::string powerRestorePolicy = dbusPowerRestorePolicyFromRedfish(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001939
Ed Tanous8d69c662023-06-21 10:29:06 -07001940 if (powerRestorePolicy.empty())
George Liuc6a620f2020-04-10 17:18:11 +08001941 {
Ed Tanousac106bf2023-06-07 09:24:59 -07001942 messages::propertyValueNotInList(asyncResp->res, policy,
Gunnar Mills4e69c902021-01-05 19:50:11 -06001943 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001944 return;
1945 }
1946
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001947 setDbusProperty(
Ginu Georgee93abac2024-06-14 17:35:27 +05301948 asyncResp, "PowerRestorePolicy", "xyz.openbmc_project.Settings",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00001949 sdbusplus::message::object_path(
1950 "/xyz/openbmc_project/control/host0/power_restore_policy"),
George Liuc6a620f2020-04-10 17:18:11 +08001951 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ginu Georgee93abac2024-06-14 17:35:27 +05301952 powerRestorePolicy);
George Liuc6a620f2020-04-10 17:18:11 +08001953}
1954
AppaRao Pulia6349912019-10-18 17:16:08 +05301955/**
1956 * @brief Retrieves provisioning status
1957 *
Ed Tanous25b54db2024-04-17 15:40:31 -07001958 * @param[in] asyncResp Shared pointer for completing asynchronous
1959 * calls.
AppaRao Pulia6349912019-10-18 17:16:08 +05301960 *
1961 * @return None.
1962 */
Ed Tanous25b54db2024-04-17 15:40:31 -07001963inline void
1964 getProvisioningStatus(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301965{
Ed Tanous62598e32023-07-17 17:06:25 -07001966 BMCWEB_LOG_DEBUG("Get OEM information.");
Ed Tanousdeae6a72024-11-11 21:58:57 -08001967 dbus::utility::getAllProperties(
1968 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1969 "xyz.openbmc_project.PFR.Attributes",
Ed Tanousac106bf2023-06-07 09:24:59 -07001970 [asyncResp](const boost::system::error_code& ec,
1971 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001972 nlohmann::json& oemPFR =
1973 asyncResp->res
1974 .jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1975 asyncResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1976 "#OpenBMCComputerSystem.v1_0_0.OpenBmc";
1977 oemPFR["@odata.type"] =
1978 "#OpenBMCComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07001979
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001980 if (ec)
AppaRao Pulia6349912019-10-18 17:16:08 +05301981 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001982 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
1983 // not an error, don't have to have the interface
Ed Tanous539d8c62024-06-19 14:38:27 -07001984 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
Patrick Williamsbd79bce2024-08-16 15:22:20 -04001985 FirmwareProvisioningStatus::NotProvisioned;
1986 return;
1987 }
1988
1989 const bool* provState = nullptr;
1990 const bool* lockState = nullptr;
1991
1992 const bool success = sdbusplus::unpackPropertiesNoThrow(
1993 dbus_utils::UnpackErrorPrinter(), propertiesList,
1994 "UfmProvisioned", provState, "UfmLocked", lockState);
1995
1996 if (!success)
1997 {
1998 messages::internalError(asyncResp->res);
1999 return;
2000 }
2001
2002 if ((provState == nullptr) || (lockState == nullptr))
2003 {
2004 BMCWEB_LOG_DEBUG("Unable to get PFR attributes.");
2005 messages::internalError(asyncResp->res);
2006 return;
2007 }
2008
2009 if (*provState)
2010 {
2011 if (*lockState)
2012 {
2013 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2014 FirmwareProvisioningStatus::ProvisionedAndLocked;
2015 }
2016 else
2017 {
2018 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
2019 FirmwareProvisioningStatus::ProvisionedButNotLocked;
2020 }
AppaRao Pulia6349912019-10-18 17:16:08 +05302021 }
2022 else
2023 {
Ed Tanous539d8c62024-06-19 14:38:27 -07002024 oemPFR["ProvisioningStatus"] = open_bmc_computer_system::
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002025 FirmwareProvisioningStatus::NotProvisioned;
AppaRao Pulia6349912019-10-18 17:16:08 +05302026 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002027 });
AppaRao Pulia6349912019-10-18 17:16:08 +05302028}
AppaRao Pulia6349912019-10-18 17:16:08 +05302029
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302030/**
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002031 * @brief Translate the PowerMode string to enum value
Chris Cain3a2d04242021-05-28 16:57:10 -05002032 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002033 * @param[in] modeString PowerMode string to be translated
Chris Cain3a2d04242021-05-28 16:57:10 -05002034 *
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002035 * @return PowerMode enum
Chris Cain3a2d04242021-05-28 16:57:10 -05002036 */
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002037inline computer_system::PowerMode
2038 translatePowerModeString(const std::string& modeString)
Chris Cain3a2d04242021-05-28 16:57:10 -05002039{
Chris Cainb6655102024-02-01 14:35:33 -06002040 using PowerMode = computer_system::PowerMode;
2041
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002042 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05002043 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002044 return PowerMode::Static;
Chris Cain3a2d04242021-05-28 16:57:10 -05002045 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002046 if (modeString ==
George Liu0fda0f12021-11-16 10:06:17 +08002047 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05002048 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002049 return PowerMode::MaximumPerformance;
Chris Cain3a2d04242021-05-28 16:57:10 -05002050 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002051 if (modeString ==
2052 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05002053 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002054 return PowerMode::PowerSaving;
Chris Cainb6655102024-02-01 14:35:33 -06002055 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002056 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002057 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance")
2058 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002059 return PowerMode::BalancedPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002060 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002061 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002062 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance")
2063 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002064 return PowerMode::EfficiencyFavorPerformance;
Chris Cainb6655102024-02-01 14:35:33 -06002065 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002066 if (modeString ==
Chris Cainb6655102024-02-01 14:35:33 -06002067 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower")
2068 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002069 return PowerMode::EfficiencyFavorPower;
Chris Cain3a2d04242021-05-28 16:57:10 -05002070 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002071 if (modeString == "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05002072 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002073 return PowerMode::OEM;
2074 }
2075 // Any other values would be invalid
2076 BMCWEB_LOG_ERROR("PowerMode value was not valid: {}", modeString);
2077 return PowerMode::Invalid;
2078}
2079
2080inline void
2081 afterGetPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2082 const boost::system::error_code& ec,
2083 const dbus::utility::DBusPropertiesMap& properties)
2084{
2085 if (ec)
2086 {
2087 BMCWEB_LOG_ERROR("DBUS response error on PowerMode GetAll: {}", ec);
2088 messages::internalError(asyncResp->res);
2089 return;
2090 }
2091
2092 std::string powerMode;
2093 const std::vector<std::string>* allowedModes = nullptr;
2094 const bool success = sdbusplus::unpackPropertiesNoThrow(
2095 dbus_utils::UnpackErrorPrinter(), properties, "PowerMode", powerMode,
2096 "AllowedPowerModes", allowedModes);
2097
2098 if (!success)
2099 {
2100 messages::internalError(asyncResp->res);
2101 return;
2102 }
2103
2104 nlohmann::json::array_t modeList;
2105 if (allowedModes == nullptr)
2106 {
2107 modeList.emplace_back("Static");
2108 modeList.emplace_back("MaximumPerformance");
2109 modeList.emplace_back("PowerSaving");
Chris Cain3a2d04242021-05-28 16:57:10 -05002110 }
2111 else
2112 {
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002113 for (const auto& aMode : *allowedModes)
2114 {
2115 computer_system::PowerMode modeValue =
2116 translatePowerModeString(aMode);
2117 if (modeValue == computer_system::PowerMode::Invalid)
2118 {
2119 messages::internalError(asyncResp->res);
2120 continue;
2121 }
2122 modeList.emplace_back(modeValue);
2123 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002124 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002125 asyncResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = modeList;
Chris Cain3a2d04242021-05-28 16:57:10 -05002126
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002127 BMCWEB_LOG_DEBUG("Current power mode: {}", powerMode);
2128 const computer_system::PowerMode modeValue =
2129 translatePowerModeString(powerMode);
2130 if (modeValue == computer_system::PowerMode::Invalid)
2131 {
2132 messages::internalError(asyncResp->res);
2133 return;
2134 }
2135 asyncResp->res.jsonValue["PowerMode"] = modeValue;
2136}
Chris Cain3a2d04242021-05-28 16:57:10 -05002137/**
2138 * @brief Retrieves system power mode
2139 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002140 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002141 *
2142 * @return None.
2143 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002144inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain3a2d04242021-05-28 16:57:10 -05002145{
Ed Tanous62598e32023-07-17 17:06:25 -07002146 BMCWEB_LOG_DEBUG("Get power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002147
2148 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002149 constexpr std::array<std::string_view, 1> interfaces = {
2150 "xyz.openbmc_project.Control.Power.Mode"};
2151 dbus::utility::getSubTree(
2152 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002153 [asyncResp](const boost::system::error_code& ec,
2154 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002155 if (ec)
2156 {
2157 BMCWEB_LOG_DEBUG(
2158 "DBUS response error on Power.Mode GetSubTree {}", ec);
2159 // This is an optional D-Bus object so just return if
2160 // error occurs
2161 return;
2162 }
2163 if (subtree.empty())
2164 {
2165 // As noted above, this is an optional interface so just return
2166 // if there is no instance found
2167 return;
2168 }
2169 if (subtree.size() > 1)
2170 {
2171 // More then one PowerMode object is not supported and is an
2172 // error
2173 BMCWEB_LOG_DEBUG(
2174 "Found more than 1 system D-Bus Power.Mode objects: {}",
2175 subtree.size());
2176 messages::internalError(asyncResp->res);
2177 return;
2178 }
2179 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2180 {
2181 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2182 messages::internalError(asyncResp->res);
2183 return;
2184 }
2185 const std::string& path = subtree[0].first;
2186 const std::string& service = subtree[0].second.begin()->first;
2187 if (service.empty())
2188 {
2189 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2190 messages::internalError(asyncResp->res);
2191 return;
2192 }
Chris Cain6b9ac4f2024-02-15 12:59:32 -06002193
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002194 // Valid Power Mode object found, now read the mode properties
Ed Tanousdeae6a72024-11-11 21:58:57 -08002195 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002196 *crow::connections::systemBus, service, path,
2197 "xyz.openbmc_project.Control.Power.Mode",
2198 [asyncResp](
2199 const boost::system::error_code& ec2,
2200 const dbus::utility::DBusPropertiesMap& properties) {
2201 afterGetPowerMode(asyncResp, ec2, properties);
2202 });
George Liue99073f2022-12-09 11:06:16 +08002203 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002204}
2205
2206/**
2207 * @brief Validate the specified mode is valid and return the PowerMode
2208 * name associated with that string
2209 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002210 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cainb6655102024-02-01 14:35:33 -06002211 * @param[in] modeValue String representing the desired PowerMode
Chris Cain3a2d04242021-05-28 16:57:10 -05002212 *
2213 * @return PowerMode value or empty string if mode is not valid
2214 */
2215inline std::string
Ed Tanousac106bf2023-06-07 09:24:59 -07002216 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cainb6655102024-02-01 14:35:33 -06002217 const nlohmann::json& modeValue)
Chris Cain3a2d04242021-05-28 16:57:10 -05002218{
Chris Cainb6655102024-02-01 14:35:33 -06002219 using PowerMode = computer_system::PowerMode;
Chris Cain3a2d04242021-05-28 16:57:10 -05002220 std::string mode;
2221
Chris Cainb6655102024-02-01 14:35:33 -06002222 if (modeValue == PowerMode::Static)
Chris Cain3a2d04242021-05-28 16:57:10 -05002223 {
2224 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2225 }
Chris Cainb6655102024-02-01 14:35:33 -06002226 else if (modeValue == PowerMode::MaximumPerformance)
Chris Cain3a2d04242021-05-28 16:57:10 -05002227 {
George Liu0fda0f12021-11-16 10:06:17 +08002228 mode =
2229 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002230 }
Chris Cainb6655102024-02-01 14:35:33 -06002231 else if (modeValue == PowerMode::PowerSaving)
Chris Cain3a2d04242021-05-28 16:57:10 -05002232 {
2233 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2234 }
Chris Cainb6655102024-02-01 14:35:33 -06002235 else if (modeValue == PowerMode::BalancedPerformance)
2236 {
2237 mode =
2238 "xyz.openbmc_project.Control.Power.Mode.PowerMode.BalancedPerformance";
2239 }
2240 else if (modeValue == PowerMode::EfficiencyFavorPerformance)
2241 {
2242 mode =
2243 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPerformance";
2244 }
2245 else if (modeValue == PowerMode::EfficiencyFavorPower)
2246 {
2247 mode =
2248 "xyz.openbmc_project.Control.Power.Mode.PowerMode.EfficiencyFavorPower";
2249 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002250 else
2251 {
Chris Cainb6655102024-02-01 14:35:33 -06002252 messages::propertyValueNotInList(asyncResp->res, modeValue.dump(),
Ed Tanousac106bf2023-06-07 09:24:59 -07002253 "PowerMode");
Chris Cain3a2d04242021-05-28 16:57:10 -05002254 }
2255 return mode;
2256}
2257
2258/**
2259 * @brief Sets system power mode.
2260 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002261 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain3a2d04242021-05-28 16:57:10 -05002262 * @param[in] pmode System power mode from request.
2263 *
2264 * @return None.
2265 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002266inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Chris Cain3a2d04242021-05-28 16:57:10 -05002267 const std::string& pmode)
2268{
Ed Tanous62598e32023-07-17 17:06:25 -07002269 BMCWEB_LOG_DEBUG("Set power mode.");
Chris Cain3a2d04242021-05-28 16:57:10 -05002270
Ed Tanousac106bf2023-06-07 09:24:59 -07002271 std::string powerMode = validatePowerMode(asyncResp, pmode);
Chris Cain3a2d04242021-05-28 16:57:10 -05002272 if (powerMode.empty())
2273 {
2274 return;
2275 }
2276
2277 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002278 constexpr std::array<std::string_view, 1> interfaces = {
2279 "xyz.openbmc_project.Control.Power.Mode"};
2280 dbus::utility::getSubTree(
2281 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002282 [asyncResp,
George Liue99073f2022-12-09 11:06:16 +08002283 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002284 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002285 if (ec)
2286 {
2287 BMCWEB_LOG_ERROR(
2288 "DBUS response error on Power.Mode GetSubTree {}", ec);
2289 // This is an optional D-Bus object, but user attempted to patch
2290 messages::internalError(asyncResp->res);
2291 return;
2292 }
2293 if (subtree.empty())
2294 {
2295 // This is an optional D-Bus object, but user attempted to patch
2296 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2297 "PowerMode");
2298 return;
2299 }
2300 if (subtree.size() > 1)
2301 {
2302 // More then one PowerMode object is not supported and is an
2303 // error
2304 BMCWEB_LOG_DEBUG(
2305 "Found more than 1 system D-Bus Power.Mode objects: {}",
2306 subtree.size());
2307 messages::internalError(asyncResp->res);
2308 return;
2309 }
2310 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2311 {
2312 BMCWEB_LOG_DEBUG("Power.Mode mapper error!");
2313 messages::internalError(asyncResp->res);
2314 return;
2315 }
2316 const std::string& path = subtree[0].first;
2317 const std::string& service = subtree[0].second.begin()->first;
2318 if (service.empty())
2319 {
2320 BMCWEB_LOG_DEBUG("Power.Mode service mapper error!");
2321 messages::internalError(asyncResp->res);
2322 return;
2323 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002324
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002325 BMCWEB_LOG_DEBUG("Setting power mode({}) -> {}", powerMode, path);
Ed Tanous002d39b2022-05-31 08:59:27 -07002326
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002327 // Set the Power Mode property
2328 setDbusProperty(asyncResp, "PowerMode", service, path,
2329 "xyz.openbmc_project.Control.Power.Mode",
2330 "PowerMode", powerMode);
2331 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002332}
2333
2334/**
Yong Li51709ff2019-09-30 14:13:04 +08002335 * @brief Translates watchdog timeout action DBUS property value to redfish.
2336 *
2337 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2338 *
2339 * @return Returns as a string, the timeout action in Redfish terms. If
2340 * translation cannot be done, returns an empty string.
2341 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002342inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002343{
2344 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2345 {
2346 return "None";
2347 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002348 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002349 {
2350 return "ResetSystem";
2351 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002352 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002353 {
2354 return "PowerDown";
2355 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002356 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002357 {
2358 return "PowerCycle";
2359 }
2360
2361 return "";
2362}
2363
2364/**
Yong Lic45f0082019-10-10 14:19:01 +08002365 *@brief Translates timeout action from Redfish to DBUS property value.
2366 *
2367 *@param[in] rfAction The timeout action in Redfish.
2368 *
2369 *@return Returns as a string, the time_out action as expected by DBUS.
2370 *If translation cannot be done, returns an empty string.
2371 */
2372
Ed Tanous23a21a12020-07-25 04:45:05 +00002373inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002374{
2375 if (rfAction == "None")
2376 {
2377 return "xyz.openbmc_project.State.Watchdog.Action.None";
2378 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002379 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002380 {
2381 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2382 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002383 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002384 {
2385 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2386 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002387 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002388 {
2389 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2390 }
2391
2392 return "";
2393}
2394
2395/**
Yong Li51709ff2019-09-30 14:13:04 +08002396 * @brief Retrieves host watchdog timer properties over DBUS
2397 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002398 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Yong Li51709ff2019-09-30 14:13:04 +08002399 *
2400 * @return None.
2401 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002402inline void
Ed Tanousac106bf2023-06-07 09:24:59 -07002403 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Yong Li51709ff2019-09-30 14:13:04 +08002404{
Ed Tanous62598e32023-07-17 17:06:25 -07002405 BMCWEB_LOG_DEBUG("Get host watchodg");
Ed Tanousdeae6a72024-11-11 21:58:57 -08002406 dbus::utility::getAllProperties(
2407 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002408 "xyz.openbmc_project.State.Watchdog",
Ed Tanousac106bf2023-06-07 09:24:59 -07002409 [asyncResp](const boost::system::error_code& ec,
2410 const dbus::utility::DBusPropertiesMap& properties) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002411 if (ec)
2412 {
2413 // watchdog service is stopped
2414 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
2415 return;
2416 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002417
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002418 BMCWEB_LOG_DEBUG("Got {} wdt prop.", properties.size());
Ed Tanous002d39b2022-05-31 08:59:27 -07002419
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002420 nlohmann::json& hostWatchdogTimer =
2421 asyncResp->res.jsonValue["HostWatchdogTimer"];
Ed Tanous002d39b2022-05-31 08:59:27 -07002422
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002423 // watchdog service is running/enabled
2424 hostWatchdogTimer["Status"]["State"] = resource::State::Enabled;
Ed Tanous002d39b2022-05-31 08:59:27 -07002425
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002426 const bool* enabled = nullptr;
2427 const std::string* expireAction = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002428
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002429 const bool success = sdbusplus::unpackPropertiesNoThrow(
2430 dbus_utils::UnpackErrorPrinter(), properties, "Enabled",
2431 enabled, "ExpireAction", expireAction);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002432
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002433 if (!success)
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002434 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002435 messages::internalError(asyncResp->res);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002436 return;
2437 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002438
2439 if (enabled != nullptr)
2440 {
2441 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2442 }
2443
2444 if (expireAction != nullptr)
2445 {
2446 std::string action = dbusToRfWatchdogAction(*expireAction);
2447 if (action.empty())
2448 {
2449 messages::internalError(asyncResp->res);
2450 return;
2451 }
2452 hostWatchdogTimer["TimeoutAction"] = action;
2453 }
2454 });
Yong Li51709ff2019-09-30 14:13:04 +08002455}
2456
2457/**
Yong Lic45f0082019-10-10 14:19:01 +08002458 * @brief Sets Host WatchDog Timer properties.
2459 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002460 * @param[in] asyncResp Shared pointer for generating response message.
Yong Lic45f0082019-10-10 14:19:01 +08002461 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2462 * RF request.
2463 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2464 *
2465 * @return None.
2466 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002467inline void
2468 setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2469 const std::optional<bool> wdtEnable,
2470 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002471{
Ed Tanous62598e32023-07-17 17:06:25 -07002472 BMCWEB_LOG_DEBUG("Set host watchdog");
Yong Lic45f0082019-10-10 14:19:01 +08002473
2474 if (wdtTimeOutAction)
2475 {
2476 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2477 // check if TimeOut Action is Valid
2478 if (wdtTimeOutActStr.empty())
2479 {
Ed Tanous62598e32023-07-17 17:06:25 -07002480 BMCWEB_LOG_DEBUG("Unsupported value for TimeoutAction: {}",
2481 *wdtTimeOutAction);
Ed Tanousac106bf2023-06-07 09:24:59 -07002482 messages::propertyValueNotInList(asyncResp->res, *wdtTimeOutAction,
Yong Lic45f0082019-10-10 14:19:01 +08002483 "TimeoutAction");
2484 return;
2485 }
2486
Ginu Georgee93abac2024-06-14 17:35:27 +05302487 setDbusProperty(asyncResp, "HostWatchdogTimer/TimeoutAction",
2488 "xyz.openbmc_project.Watchdog",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00002489 sdbusplus::message::object_path(
2490 "/xyz/openbmc_project/watchdog/host0"),
2491 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ginu Georgee93abac2024-06-14 17:35:27 +05302492 wdtTimeOutActStr);
Yong Lic45f0082019-10-10 14:19:01 +08002493 }
2494
2495 if (wdtEnable)
2496 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302497 setDbusProperty(asyncResp, "HostWatchdogTimer/FunctionEnabled",
2498 "xyz.openbmc_project.Watchdog",
Asmitha Karunanithi87c44962024-04-04 18:28:33 +00002499 sdbusplus::message::object_path(
2500 "/xyz/openbmc_project/watchdog/host0"),
2501 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ginu Georgee93abac2024-06-14 17:35:27 +05302502 *wdtEnable);
Yong Lic45f0082019-10-10 14:19:01 +08002503 }
2504}
2505
Chris Cain37bbf982021-09-20 10:53:09 -05002506/**
2507 * @brief Parse the Idle Power Saver properties into json
2508 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002509 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002510 * @param[in] properties IPS property data from DBus.
2511 *
2512 * @return true if successful
2513 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002514inline bool
Ed Tanousac106bf2023-06-07 09:24:59 -07002515 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002516 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002517{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002518 const bool* enabled = nullptr;
2519 const uint8_t* enterUtilizationPercent = nullptr;
2520 const uint64_t* enterDwellTime = nullptr;
2521 const uint8_t* exitUtilizationPercent = nullptr;
2522 const uint64_t* exitDwellTime = nullptr;
2523
2524 const bool success = sdbusplus::unpackPropertiesNoThrow(
2525 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
Chris Cain2661b722023-03-22 08:53:21 -05002526 "EnterUtilizationPercent", enterUtilizationPercent, "EnterDwellTime",
2527 enterDwellTime, "ExitUtilizationPercent", exitUtilizationPercent,
2528 "ExitDwellTime", exitDwellTime);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002529
2530 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002531 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002532 return false;
2533 }
2534
2535 if (enabled != nullptr)
2536 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002537 asyncResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002538 }
2539
2540 if (enterUtilizationPercent != nullptr)
2541 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002542 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002543 *enterUtilizationPercent;
2544 }
2545
2546 if (enterDwellTime != nullptr)
2547 {
2548 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002549 asyncResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002550 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2551 .count();
2552 }
2553
2554 if (exitUtilizationPercent != nullptr)
2555 {
Ed Tanousac106bf2023-06-07 09:24:59 -07002556 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002557 *exitUtilizationPercent;
2558 }
2559
2560 if (exitDwellTime != nullptr)
2561 {
2562 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
Ed Tanousac106bf2023-06-07 09:24:59 -07002563 asyncResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002564 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2565 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002566 }
2567
2568 return true;
2569}
2570
2571/**
2572 * @brief Retrieves host watchdog timer properties over DBUS
2573 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002574 * @param[in] asyncResp Shared pointer for completing asynchronous calls.
Chris Cain37bbf982021-09-20 10:53:09 -05002575 *
2576 * @return None.
2577 */
Ed Tanousac106bf2023-06-07 09:24:59 -07002578inline void
2579 getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Chris Cain37bbf982021-09-20 10:53:09 -05002580{
Ed Tanous62598e32023-07-17 17:06:25 -07002581 BMCWEB_LOG_DEBUG("Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002582
2583 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002584 constexpr std::array<std::string_view, 1> interfaces = {
2585 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2586 dbus::utility::getSubTree(
2587 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002588 [asyncResp](const boost::system::error_code& ec,
2589 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002590 if (ec)
Chris Cain37bbf982021-09-20 10:53:09 -05002591 {
Ed Tanous62598e32023-07-17 17:06:25 -07002592 BMCWEB_LOG_ERROR(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002593 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2594 ec);
2595 messages::internalError(asyncResp->res);
2596 return;
2597 }
2598 if (subtree.empty())
2599 {
2600 // This is an optional interface so just return
2601 // if there is no instance found
2602 BMCWEB_LOG_DEBUG("No instances found");
2603 return;
2604 }
2605 if (subtree.size() > 1)
2606 {
2607 // More then one PowerIdlePowerSaver object is not supported and
2608 // is an error
2609 BMCWEB_LOG_DEBUG("Found more than 1 system D-Bus "
2610 "Power.IdlePowerSaver objects: {}",
2611 subtree.size());
2612 messages::internalError(asyncResp->res);
2613 return;
2614 }
2615 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2616 {
2617 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2618 messages::internalError(asyncResp->res);
2619 return;
2620 }
2621 const std::string& path = subtree[0].first;
2622 const std::string& service = subtree[0].second.begin()->first;
2623 if (service.empty())
2624 {
2625 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
Ed Tanousac106bf2023-06-07 09:24:59 -07002626 messages::internalError(asyncResp->res);
Chris Cain37bbf982021-09-20 10:53:09 -05002627 return;
2628 }
2629
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002630 // Valid IdlePowerSaver object found, now read the current values
Ed Tanousdeae6a72024-11-11 21:58:57 -08002631 dbus::utility::getAllProperties(
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002632 *crow::connections::systemBus, service, path,
2633 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2634 [asyncResp](
2635 const boost::system::error_code& ec2,
2636 const dbus::utility::DBusPropertiesMap& properties) {
2637 if (ec2)
2638 {
2639 BMCWEB_LOG_ERROR(
2640 "DBUS response error on IdlePowerSaver GetAll: {}",
2641 ec2);
2642 messages::internalError(asyncResp->res);
2643 return;
2644 }
2645
2646 if (!parseIpsProperties(asyncResp, properties))
2647 {
2648 messages::internalError(asyncResp->res);
2649 return;
2650 }
2651 });
George Liue99073f2022-12-09 11:06:16 +08002652 });
Chris Cain37bbf982021-09-20 10:53:09 -05002653
Ed Tanous62598e32023-07-17 17:06:25 -07002654 BMCWEB_LOG_DEBUG("EXIT: Get idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002655}
2656
2657/**
2658 * @brief Sets Idle Power Saver properties.
2659 *
Ed Tanousac106bf2023-06-07 09:24:59 -07002660 * @param[in] asyncResp Shared pointer for generating response message.
Chris Cain37bbf982021-09-20 10:53:09 -05002661 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2662 * RF request.
2663 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2664 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2665 * before entering idle state.
2666 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2667 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2668 * before exiting idle state
2669 *
2670 * @return None.
2671 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002672inline void setIdlePowerSaver(
2673 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2674 const std::optional<bool> ipsEnable,
2675 const std::optional<uint8_t> ipsEnterUtil,
2676 const std::optional<uint64_t> ipsEnterTime,
2677 const std::optional<uint8_t> ipsExitUtil,
2678 const std::optional<uint64_t> ipsExitTime)
Chris Cain37bbf982021-09-20 10:53:09 -05002679{
Ed Tanous62598e32023-07-17 17:06:25 -07002680 BMCWEB_LOG_DEBUG("Set idle power saver properties");
Chris Cain37bbf982021-09-20 10:53:09 -05002681
2682 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002683 constexpr std::array<std::string_view, 1> interfaces = {
2684 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2685 dbus::utility::getSubTree(
2686 "/", 0, interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -07002687 [asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002688 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002689 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002690 if (ec)
2691 {
2692 BMCWEB_LOG_ERROR(
2693 "DBUS response error on Power.IdlePowerSaver GetSubTree {}",
2694 ec);
2695 messages::internalError(asyncResp->res);
2696 return;
2697 }
2698 if (subtree.empty())
2699 {
2700 // This is an optional D-Bus object, but user attempted to patch
2701 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2702 "IdlePowerSaver");
2703 return;
2704 }
2705 if (subtree.size() > 1)
2706 {
2707 // More then one PowerIdlePowerSaver object is not supported and
2708 // is an error
2709 BMCWEB_LOG_DEBUG(
2710 "Found more than 1 system D-Bus Power.IdlePowerSaver objects: {}",
2711 subtree.size());
2712 messages::internalError(asyncResp->res);
2713 return;
2714 }
2715 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2716 {
2717 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver mapper error!");
2718 messages::internalError(asyncResp->res);
2719 return;
2720 }
2721 const std::string& path = subtree[0].first;
2722 const std::string& service = subtree[0].second.begin()->first;
2723 if (service.empty())
2724 {
2725 BMCWEB_LOG_DEBUG("Power.IdlePowerSaver service mapper error!");
2726 messages::internalError(asyncResp->res);
2727 return;
2728 }
Chris Cain37bbf982021-09-20 10:53:09 -05002729
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002730 // Valid Power IdlePowerSaver object found, now set any values that
2731 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002732
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002733 if (ipsEnable)
2734 {
2735 setDbusProperty(
2736 asyncResp, "IdlePowerSaver/Enabled", service, path,
2737 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2738 "Enabled", *ipsEnable);
2739 }
2740 if (ipsEnterUtil)
2741 {
2742 setDbusProperty(
2743 asyncResp, "IdlePowerSaver/EnterUtilizationPercent",
2744 service, path,
2745 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2746 "EnterUtilizationPercent", *ipsEnterUtil);
2747 }
2748 if (ipsEnterTime)
2749 {
2750 // Convert from seconds into milliseconds for DBus
2751 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2752 setDbusProperty(
2753 asyncResp, "IdlePowerSaver/EnterDwellTimeSeconds", service,
2754 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2755 "EnterDwellTime", timeMilliseconds);
2756 }
2757 if (ipsExitUtil)
2758 {
2759 setDbusProperty(
2760 asyncResp, "IdlePowerSaver/ExitUtilizationPercent", service,
2761 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2762 "ExitUtilizationPercent", *ipsExitUtil);
2763 }
2764 if (ipsExitTime)
2765 {
2766 // Convert from seconds into milliseconds for DBus
2767 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2768 setDbusProperty(
2769 asyncResp, "IdlePowerSaver/ExitDwellTimeSeconds", service,
2770 path, "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2771 "ExitDwellTime", timeMilliseconds);
2772 }
2773 });
Chris Cain37bbf982021-09-20 10:53:09 -05002774
Ed Tanous62598e32023-07-17 17:06:25 -07002775 BMCWEB_LOG_DEBUG("EXIT: Set idle power saver parameters");
Chris Cain37bbf982021-09-20 10:53:09 -05002776}
2777
Ed Tanousc1e219d2023-06-07 10:34:33 -07002778inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002779 crow::App& app, const crow::Request& req,
2780 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2781{
2782 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2783 {
2784 return;
2785 }
2786 asyncResp->res.addHeader(
2787 boost::beast::http::field::link,
2788 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2789}
2790
Ed Tanousc1e219d2023-06-07 10:34:33 -07002791inline void handleComputerSystemCollectionGet(
2792 crow::App& app, const crow::Request& req,
2793 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2794{
2795 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2796 {
2797 return;
2798 }
2799
2800 asyncResp->res.addHeader(
2801 boost::beast::http::field::link,
2802 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
2803 asyncResp->res.jsonValue["@odata.type"] =
2804 "#ComputerSystemCollection.ComputerSystemCollection";
2805 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2806 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
2807
2808 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2809 ifaceArray = nlohmann::json::array();
Ed Tanous25b54db2024-04-17 15:40:31 -07002810 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002811 {
2812 asyncResp->res.jsonValue["Members@odata.count"] = 0;
2813 // Option currently returns no systems. TBD
2814 return;
2815 }
2816 asyncResp->res.jsonValue["Members@odata.count"] = 1;
2817 nlohmann::json::object_t system;
Ed Tanous253f11b2024-05-16 09:38:31 -07002818 system["@odata.id"] = boost::urls::format("/redfish/v1/Systems/{}",
2819 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002820 ifaceArray.emplace_back(std::move(system));
Gunnar Mills68896202024-08-21 11:34:20 -05002821
2822 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2823 {
2824 BMCWEB_LOG_DEBUG("Hypervisor is available");
2825 asyncResp->res.jsonValue["Members@odata.count"] = 2;
2826
2827 nlohmann::json::object_t hypervisor;
2828 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2829 ifaceArray.emplace_back(std::move(hypervisor));
2830 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07002831}
2832
Yong Lic45f0082019-10-10 14:19:01 +08002833/**
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002834 * Function transceives data with dbus directly.
2835 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002836inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002837{
Patrick Williams89492a12023-05-10 07:51:34 -05002838 constexpr const char* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2839 constexpr const char* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2840 constexpr const char* interfaceName =
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002841 "xyz.openbmc_project.Control.Host.NMI";
Patrick Williams89492a12023-05-10 07:51:34 -05002842 constexpr const char* method = "NMI";
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002843
2844 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002845 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04002846 if (ec)
2847 {
2848 BMCWEB_LOG_ERROR(" Bad D-Bus request error: {}", ec);
2849 messages::internalError(asyncResp->res);
2850 return;
2851 }
2852 messages::success(asyncResp->res);
2853 },
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002854 serviceName, objectPath, interfaceName, method);
2855}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002856
Ed Tanousc1e219d2023-06-07 10:34:33 -07002857inline void handleComputerSystemResetActionPost(
2858 crow::App& app, const crow::Request& req,
2859 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2860 const std::string& systemName)
2861{
2862 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2863 {
2864 return;
2865 }
Gunnar Millsdd7090e2024-07-30 15:23:05 -05002866
2867 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
2868 {
2869 if (systemName == "hypervisor")
2870 {
2871 handleHypervisorSystemResetPost(req, asyncResp);
2872 return;
2873 }
2874 }
2875
Ed Tanous253f11b2024-05-16 09:38:31 -07002876 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002877 {
2878 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2879 systemName);
2880 return;
2881 }
Ed Tanous25b54db2024-04-17 15:40:31 -07002882 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07002883 {
2884 // Option currently returns no systems. TBD
2885 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2886 systemName);
2887 return;
2888 }
2889 std::string resetType;
2890 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
2891 {
2892 return;
2893 }
2894
2895 // Get the command and host vs. chassis
2896 std::string command;
2897 bool hostCommand = true;
2898 if ((resetType == "On") || (resetType == "ForceOn"))
2899 {
2900 command = "xyz.openbmc_project.State.Host.Transition.On";
2901 hostCommand = true;
2902 }
2903 else if (resetType == "ForceOff")
2904 {
2905 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2906 hostCommand = false;
2907 }
2908 else if (resetType == "ForceRestart")
2909 {
2910 command = "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2911 hostCommand = true;
2912 }
2913 else if (resetType == "GracefulShutdown")
2914 {
2915 command = "xyz.openbmc_project.State.Host.Transition.Off";
2916 hostCommand = true;
2917 }
2918 else if (resetType == "GracefulRestart")
2919 {
2920 command =
2921 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2922 hostCommand = true;
2923 }
2924 else if (resetType == "PowerCycle")
2925 {
2926 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2927 hostCommand = true;
2928 }
2929 else if (resetType == "Nmi")
2930 {
2931 doNMI(asyncResp);
2932 return;
2933 }
2934 else
2935 {
2936 messages::actionParameterUnknown(asyncResp->res, "Reset", resetType);
2937 return;
2938 }
Ed Tanousd02aad32024-02-13 14:43:34 -08002939 sdbusplus::message::object_path statePath("/xyz/openbmc_project/state");
Ed Tanousc1e219d2023-06-07 10:34:33 -07002940
2941 if (hostCommand)
2942 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302943 setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Host",
Ed Tanousd02aad32024-02-13 14:43:34 -08002944 statePath / "host0", "xyz.openbmc_project.State.Host",
Ginu Georgee93abac2024-06-14 17:35:27 +05302945 "RequestedHostTransition", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002946 }
2947 else
2948 {
Ginu Georgee93abac2024-06-14 17:35:27 +05302949 setDbusProperty(asyncResp, "Reset", "xyz.openbmc_project.State.Chassis",
Ed Tanousd02aad32024-02-13 14:43:34 -08002950 statePath / "chassis0",
2951 "xyz.openbmc_project.State.Chassis",
Ginu Georgee93abac2024-06-14 17:35:27 +05302952 "RequestedPowerTransition", command);
Ed Tanousc1e219d2023-06-07 10:34:33 -07002953 }
2954}
2955
Ed Tanousc1e219d2023-06-07 10:34:33 -07002956inline void handleComputerSystemHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002957 App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08002958 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2959 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002960{
2961 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2962 {
2963 return;
2964 }
2965
2966 asyncResp->res.addHeader(
2967 boost::beast::http::field::link,
2968 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2969}
2970
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002971inline void afterPortRequest(
2972 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2973 const boost::system::error_code& ec,
2974 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
2975{
2976 if (ec)
2977 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002978 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002979 messages::internalError(asyncResp->res);
2980 return;
2981 }
2982 for (const auto& data : socketData)
2983 {
2984 const std::string& socketPath = get<0>(data);
2985 const std::string& protocolName = get<1>(data);
2986 bool isProtocolEnabled = get<2>(data);
2987 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
2988 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
2989 // need to retrieve port number for
2990 // obmc-console-ssh service
2991 if (protocolName == "SSH")
2992 {
2993 getPortNumber(socketPath, [asyncResp, protocolName](
Ed Tanous81c4e332023-05-18 10:30:34 -07002994 const boost::system::error_code& ec1,
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002995 int portNumber) {
2996 if (ec1)
2997 {
Gunnar Millsb3e86cb2023-08-31 13:01:14 -05002998 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002999 messages::internalError(asyncResp->res);
3000 return;
3001 }
3002 nlohmann::json& dataJson1 =
3003 asyncResp->res.jsonValue["SerialConsole"];
3004 dataJson1[protocolName]["Port"] = portNumber;
3005 });
3006 }
3007 }
3008}
Ed Tanousc1e219d2023-06-07 10:34:33 -07003009
3010inline void
3011 handleComputerSystemGet(crow::App& app, const crow::Request& req,
3012 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3013 const std::string& systemName)
Ed Tanous1abe55e2018-09-05 08:30:59 -07003014{
Ed Tanousc1e219d2023-06-07 10:34:33 -07003015 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3016 {
3017 return;
3018 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003019
Ed Tanous25b54db2024-04-17 15:40:31 -07003020 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003021 {
3022 // Option currently returns no systems. TBD
3023 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3024 systemName);
3025 return;
3026 }
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003027
Gunnar Mills68896202024-08-21 11:34:20 -05003028 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003029 {
Gunnar Mills68896202024-08-21 11:34:20 -05003030 if (systemName == "hypervisor")
3031 {
3032 handleHypervisorSystemGet(asyncResp);
3033 return;
3034 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003035 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003036
Ed Tanous253f11b2024-05-16 09:38:31 -07003037 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003038 {
3039 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3040 systemName);
3041 return;
3042 }
3043 asyncResp->res.addHeader(
3044 boost::beast::http::field::link,
3045 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3046 asyncResp->res.jsonValue["@odata.type"] =
Chris Cainb6655102024-02-01 14:35:33 -06003047 "#ComputerSystem.v1_22_0.ComputerSystem";
Ed Tanous253f11b2024-05-16 09:38:31 -07003048 asyncResp->res.jsonValue["Name"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
3049 asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_SYSTEM_URI_NAME;
Ed Tanous539d8c62024-06-19 14:38:27 -07003050 asyncResp->res.jsonValue["SystemType"] =
3051 computer_system::SystemType::Physical;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003052 asyncResp->res.jsonValue["Description"] = "Computer System";
3053 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003054 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
Priyanga Ramasamydfb2b402023-07-06 08:37:08 -05003055 double(0);
Ed Tanous253f11b2024-05-16 09:38:31 -07003056 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
3057 "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous04a258f2018-10-15 08:00:41 -07003058
Ed Tanous253f11b2024-05-16 09:38:31 -07003059 asyncResp->res.jsonValue["Processors"]["@odata.id"] = boost::urls::format(
3060 "/redfish/v1/Systems/{}/Processors", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3061 asyncResp->res.jsonValue["Memory"]["@odata.id"] = boost::urls::format(
3062 "/redfish/v1/Systems/{}/Memory", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3063 asyncResp->res.jsonValue["Storage"]["@odata.id"] = boost::urls::format(
3064 "/redfish/v1/Systems/{}/Storage", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003065 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003066 boost::urls::format("/redfish/v1/Systems/{}/FabricAdapters",
3067 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanous029573d2019-02-01 10:57:49 -08003068
Ed Tanousc1e219d2023-06-07 10:34:33 -07003069 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003070 boost::urls::format(
3071 "/redfish/v1/Systems/{}/Actions/ComputerSystem.Reset",
3072 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003073 asyncResp->res
3074 .jsonValue["Actions"]["#ComputerSystem.Reset"]["@Redfish.ActionInfo"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003075 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3076 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02003077
Ed Tanous253f11b2024-05-16 09:38:31 -07003078 asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
3079 "/redfish/v1/Systems/{}/LogServices", BMCWEB_REDFISH_SYSTEM_URI_NAME);
3080 asyncResp->res.jsonValue["Bios"]["@odata.id"] = boost::urls::format(
3081 "/redfish/v1/Systems/{}/Bios", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Jason M. Billsc4bf6372018-11-05 13:48:27 -08003082
Ed Tanousc1e219d2023-06-07 10:34:33 -07003083 nlohmann::json::array_t managedBy;
3084 nlohmann::json& manager = managedBy.emplace_back();
Ed Tanous253f11b2024-05-16 09:38:31 -07003085 manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
3086 BMCWEB_REDFISH_MANAGER_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003087 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
Ed Tanous539d8c62024-06-19 14:38:27 -07003088 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
3089 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003090
Ed Tanousc1e219d2023-06-07 10:34:33 -07003091 // Fill in SerialConsole info
3092 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3093 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] = true;
Ed Tanous14766872022-03-15 10:44:42 -07003094
Ed Tanousc1e219d2023-06-07 10:34:33 -07003095 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] = true;
3096 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3097 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3098 "Press ~. to exit console";
3099 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3100 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003101
Ed Tanous25b54db2024-04-17 15:40:31 -07003102 if constexpr (BMCWEB_KVM)
3103 {
3104 // Fill in GraphicalConsole info
3105 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3106 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3107 4;
3108 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3109 nlohmann::json::array_t({"KVMIP"});
3110 }
James Feistb49ac872019-05-21 15:12:01 -07003111
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003112 getMainChassisId(
3113 asyncResp, [](const std::string& chassisId,
3114 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3115 nlohmann::json::array_t chassisArray;
3116 nlohmann::json& chassis = chassisArray.emplace_back();
3117 chassis["@odata.id"] =
3118 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
3119 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3120 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003121
George Liu59a17e42022-10-08 09:27:47 +08003122 getSystemLocationIndicatorActive(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003123 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3124 getIndicatorLedState(asyncResp);
Gunnar Mills51bd2d82024-04-01 15:25:51 -05003125 getComputerSystem(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003126 getHostState(asyncResp);
3127 getBootProperties(asyncResp);
3128 getBootProgress(asyncResp);
3129 getBootProgressLastStateTime(asyncResp);
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -05003130 pcie_util::getPCIeDeviceList(asyncResp,
3131 nlohmann::json::json_pointer("/PCIeDevices"));
Ed Tanousc1e219d2023-06-07 10:34:33 -07003132 getHostWatchdogTimer(asyncResp);
3133 getPowerRestorePolicy(asyncResp);
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003134 getStopBootOnFault(asyncResp);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003135 getAutomaticRetryPolicy(asyncResp);
3136 getLastResetTime(asyncResp);
Ed Tanous25b54db2024-04-17 15:40:31 -07003137 if constexpr (BMCWEB_REDFISH_PROVISIONING_FEATURE)
3138 {
3139 getProvisioningStatus(asyncResp);
3140 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003141 getTrustedModuleRequiredToBoot(asyncResp);
3142 getPowerMode(asyncResp);
3143 getIdlePowerSaver(asyncResp);
3144}
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003145
Ed Tanousc1e219d2023-06-07 10:34:33 -07003146inline void handleComputerSystemPatch(
3147 crow::App& app, const crow::Request& req,
3148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3149 const std::string& systemName)
3150{
3151 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3152 {
3153 return;
3154 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003155 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003156 {
3157 // Option currently returns no systems. TBD
3158 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3159 systemName);
3160 return;
3161 }
Ed Tanous253f11b2024-05-16 09:38:31 -07003162 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003163 {
3164 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3165 systemName);
3166 return;
3167 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003168
Ed Tanousc1e219d2023-06-07 10:34:33 -07003169 asyncResp->res.addHeader(
3170 boost::beast::http::field::link,
3171 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003172
Ed Tanousc1e219d2023-06-07 10:34:33 -07003173 std::optional<bool> locationIndicatorActive;
3174 std::optional<std::string> indicatorLed;
3175 std::optional<std::string> assetTag;
3176 std::optional<std::string> powerRestorePolicy;
3177 std::optional<std::string> powerMode;
3178 std::optional<bool> wdtEnable;
3179 std::optional<std::string> wdtTimeOutAction;
3180 std::optional<std::string> bootSource;
3181 std::optional<std::string> bootType;
3182 std::optional<std::string> bootEnable;
3183 std::optional<std::string> bootAutomaticRetry;
3184 std::optional<uint32_t> bootAutomaticRetryAttempts;
3185 std::optional<bool> bootTrustedModuleRequired;
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003186 std::optional<std::string> stopBootOnFault;
Ed Tanousc1e219d2023-06-07 10:34:33 -07003187 std::optional<bool> ipsEnable;
3188 std::optional<uint8_t> ipsEnterUtil;
3189 std::optional<uint64_t> ipsEnterTime;
3190 std::optional<uint8_t> ipsExitUtil;
3191 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003192
Myung Baeafc474a2024-10-09 00:53:29 -07003193 if (!json_util::readJsonPatch( //
3194 req, asyncResp->res, //
3195 "AssetTag", assetTag, //
3196 "Boot/AutomaticRetryAttempts", bootAutomaticRetryAttempts, //
3197 "Boot/AutomaticRetryConfig", bootAutomaticRetry, //
3198 "Boot/BootSourceOverrideEnabled", bootEnable, //
3199 "Boot/BootSourceOverrideMode", bootType, //
3200 "Boot/BootSourceOverrideTarget", bootSource, //
3201 "Boot/StopBootOnFault", stopBootOnFault, //
3202 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired, //
3203 "HostWatchdogTimer/FunctionEnabled", wdtEnable, //
3204 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction, //
3205 "IdlePowerSaver/Enabled", ipsEnable, //
3206 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime, //
3207 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil, //
3208 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime, //
3209 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil, //
3210 "IndicatorLED", indicatorLed, //
3211 "LocationIndicatorActive", locationIndicatorActive, //
3212 "PowerMode", powerMode, //
3213 "PowerRestorePolicy", powerRestorePolicy //
3214 ))
Ed Tanousab344222024-08-07 18:01:23 -07003215 {
3216 return;
3217 }
James Feistb49ac872019-05-21 15:12:01 -07003218
Ed Tanousc1e219d2023-06-07 10:34:33 -07003219 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003220
Ed Tanousc1e219d2023-06-07 10:34:33 -07003221 if (assetTag)
3222 {
3223 setAssetTag(asyncResp, *assetTag);
3224 }
James Feistb49ac872019-05-21 15:12:01 -07003225
Ed Tanousc1e219d2023-06-07 10:34:33 -07003226 if (wdtEnable || wdtTimeOutAction)
3227 {
3228 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3229 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003230
Ed Tanousc1e219d2023-06-07 10:34:33 -07003231 if (bootSource || bootType || bootEnable)
3232 {
3233 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3234 }
3235 if (bootAutomaticRetry)
3236 {
3237 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3238 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003239
Ed Tanousc1e219d2023-06-07 10:34:33 -07003240 if (bootAutomaticRetryAttempts)
3241 {
3242 setAutomaticRetryAttempts(asyncResp,
3243 bootAutomaticRetryAttempts.value());
3244 }
Corey Hardesty797d5da2022-04-26 17:54:52 +08003245
Ed Tanousc1e219d2023-06-07 10:34:33 -07003246 if (bootTrustedModuleRequired)
3247 {
3248 setTrustedModuleRequiredToBoot(asyncResp, *bootTrustedModuleRequired);
3249 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003250
Albert Zhang9dcfe8c2021-07-05 09:38:06 +08003251 if (stopBootOnFault)
3252 {
3253 setStopBootOnFault(asyncResp, *stopBootOnFault);
3254 }
3255
Ed Tanousc1e219d2023-06-07 10:34:33 -07003256 if (locationIndicatorActive)
3257 {
George Liu59a17e42022-10-08 09:27:47 +08003258 setSystemLocationIndicatorActive(asyncResp, *locationIndicatorActive);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003259 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003260
Ed Tanousc1e219d2023-06-07 10:34:33 -07003261 // TODO (Gunnar): Remove IndicatorLED after enough time has
3262 // passed
3263 if (indicatorLed)
3264 {
3265 setIndicatorLedState(asyncResp, *indicatorLed);
3266 asyncResp->res.addHeader(boost::beast::http::field::warning,
3267 "299 - \"IndicatorLED is deprecated. Use "
3268 "LocationIndicatorActive instead.\"");
3269 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003270
Ed Tanousc1e219d2023-06-07 10:34:33 -07003271 if (powerRestorePolicy)
3272 {
3273 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3274 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003275
Ed Tanousc1e219d2023-06-07 10:34:33 -07003276 if (powerMode)
3277 {
3278 setPowerMode(asyncResp, *powerMode);
3279 }
Chris Cain37bbf982021-09-20 10:53:09 -05003280
Ed Tanousc1e219d2023-06-07 10:34:33 -07003281 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil || ipsExitTime)
3282 {
3283 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3284 ipsExitUtil, ipsExitTime);
3285 }
3286}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303287
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003288inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003289 crow::App& app, const crow::Request& req,
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003290 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanousc1e219d2023-06-07 10:34:33 -07003291 const std::string& /*systemName*/)
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003292{
3293 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3294 {
3295 return;
3296 }
3297 asyncResp->res.addHeader(
3298 boost::beast::http::field::link,
3299 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3300}
Andrew Geissler33e1f122024-02-26 21:10:16 -06003301
3302/**
3303 * @brief Translates allowed host transitions to redfish string
3304 *
3305 * @param[in] dbusAllowedHostTran The allowed host transition on dbus
3306 * @param[out] allowableValues The translated host transition(s)
3307 *
Manojkiran Edaefff2b52024-06-18 18:01:46 +05303308 * @return Emplaces corresponding Redfish translated value(s) in
Andrew Geissler33e1f122024-02-26 21:10:16 -06003309 * allowableValues. If translation not possible, does nothing to
3310 * allowableValues.
3311 */
3312inline void
3313 dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
3314 nlohmann::json::array_t& allowableValues)
3315{
3316 if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
3317 {
3318 allowableValues.emplace_back(resource::ResetType::On);
3319 allowableValues.emplace_back(resource::ResetType::ForceOn);
3320 }
3321 else if (dbusAllowedHostTran ==
3322 "xyz.openbmc_project.State.Host.Transition.Off")
3323 {
3324 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3325 }
3326 else if (dbusAllowedHostTran ==
3327 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
3328 {
3329 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3330 }
3331 else if (dbusAllowedHostTran ==
3332 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
3333 {
3334 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3335 }
3336 else
3337 {
3338 BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
3339 }
3340}
3341
3342inline void afterGetAllowedHostTransitions(
3343 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3344 const boost::system::error_code& ec,
3345 const std::vector<std::string>& allowedHostTransitions)
3346{
3347 nlohmann::json::array_t allowableValues;
3348
3349 // Supported on all systems currently
3350 allowableValues.emplace_back(resource::ResetType::ForceOff);
3351 allowableValues.emplace_back(resource::ResetType::PowerCycle);
3352 allowableValues.emplace_back(resource::ResetType::Nmi);
3353
3354 if (ec)
3355 {
Ed Tanouse715d142024-03-07 15:47:37 -08003356 if ((ec.value() ==
3357 boost::system::linux_error::bad_request_descriptor) ||
3358 (ec.value() == boost::asio::error::basic_errors::host_unreachable))
Andrew Geissler33e1f122024-02-26 21:10:16 -06003359 {
3360 // Property not implemented so just return defaults
3361 BMCWEB_LOG_DEBUG("Property not available {}", ec);
3362 allowableValues.emplace_back(resource::ResetType::On);
3363 allowableValues.emplace_back(resource::ResetType::ForceOn);
3364 allowableValues.emplace_back(resource::ResetType::ForceRestart);
3365 allowableValues.emplace_back(resource::ResetType::GracefulRestart);
3366 allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
3367 }
3368 else
3369 {
3370 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
3371 messages::internalError(asyncResp->res);
3372 return;
3373 }
3374 }
3375 else
3376 {
3377 for (const std::string& transition : allowedHostTransitions)
3378 {
3379 BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
3380 dbusToRfAllowedHostTransitions(transition, allowableValues);
3381 }
3382 }
3383
3384 nlohmann::json::object_t parameter;
3385 parameter["Name"] = "ResetType";
3386 parameter["Required"] = true;
Ed Tanous539d8c62024-06-19 14:38:27 -07003387 parameter["DataType"] = action_info::ParameterTypes::String;
Andrew Geissler33e1f122024-02-26 21:10:16 -06003388 parameter["AllowableValues"] = std::move(allowableValues);
3389 nlohmann::json::array_t parameters;
3390 parameters.emplace_back(std::move(parameter));
3391 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
3392}
3393
Ed Tanousc1e219d2023-06-07 10:34:33 -07003394inline void handleSystemCollectionResetActionGet(
3395 crow::App& app, const crow::Request& req,
3396 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3397 const std::string& systemName)
3398{
3399 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3400 {
3401 return;
3402 }
Ed Tanous25b54db2024-04-17 15:40:31 -07003403 if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003404 {
3405 // Option currently returns no systems. TBD
3406 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3407 systemName);
3408 return;
3409 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003410
Gunnar Mills68896202024-08-21 11:34:20 -05003411 if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003412 {
Gunnar Mills68896202024-08-21 11:34:20 -05003413 if (systemName == "hypervisor")
3414 {
3415 handleHypervisorResetActionGet(asyncResp);
3416 return;
3417 }
Ed Tanousc1e219d2023-06-07 10:34:33 -07003418 }
3419
Ed Tanous253f11b2024-05-16 09:38:31 -07003420 if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003421 {
3422 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3423 systemName);
3424 return;
3425 }
3426
3427 asyncResp->res.addHeader(
3428 boost::beast::http::field::link,
3429 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3430
3431 asyncResp->res.jsonValue["@odata.id"] =
Ed Tanous253f11b2024-05-16 09:38:31 -07003432 boost::urls::format("/redfish/v1/Systems/{}/ResetActionInfo",
3433 BMCWEB_REDFISH_SYSTEM_URI_NAME);
Ed Tanousc1e219d2023-06-07 10:34:33 -07003434 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
3435 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3436 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
3437
Andrew Geissler33e1f122024-02-26 21:10:16 -06003438 // Look to see if system defines AllowedHostTransitions
Ed Tanousdeae6a72024-11-11 21:58:57 -08003439 dbus::utility::getProperty<std::vector<std::string>>(
3440 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
3441 "xyz.openbmc_project.State.Host", "AllowedHostTransitions",
Andrew Geissler33e1f122024-02-26 21:10:16 -06003442 [asyncResp](const boost::system::error_code& ec,
3443 const std::vector<std::string>& allowedHostTransitions) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -04003444 afterGetAllowedHostTransitions(asyncResp, ec,
3445 allowedHostTransitions);
3446 });
Ed Tanousc1e219d2023-06-07 10:34:33 -07003447}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303448/**
3449 * SystemResetActionInfo derived class for delivering Computer Systems
3450 * ResetType AllowableValues using ResetInfo schema.
3451 */
Ed Tanous100afe52023-06-07 13:30:46 -07003452inline void requestRoutesSystems(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303453{
Ed Tanous100afe52023-06-07 13:30:46 -07003454 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3455 .privileges(redfish::privileges::headComputerSystemCollection)
3456 .methods(boost::beast::http::verb::head)(
3457 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
3458
3459 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
3460 .privileges(redfish::privileges::getComputerSystemCollection)
3461 .methods(boost::beast::http::verb::get)(
3462 std::bind_front(handleComputerSystemCollectionGet, std::ref(app)));
3463
3464 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3465 .privileges(redfish::privileges::headComputerSystem)
3466 .methods(boost::beast::http::verb::head)(
3467 std::bind_front(handleComputerSystemHead, std::ref(app)));
3468
3469 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3470 .privileges(redfish::privileges::getComputerSystem)
3471 .methods(boost::beast::http::verb::get)(
3472 std::bind_front(handleComputerSystemGet, std::ref(app)));
3473
3474 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
3475 .privileges(redfish::privileges::patchComputerSystem)
3476 .methods(boost::beast::http::verb::patch)(
3477 std::bind_front(handleComputerSystemPatch, std::ref(app)));
3478
3479 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/")
3480 .privileges(redfish::privileges::postComputerSystem)
3481 .methods(boost::beast::http::verb::post)(std::bind_front(
3482 handleComputerSystemResetActionPost, std::ref(app)));
3483
Ed Tanous7f3e84a2022-12-28 16:22:54 -08003484 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003485 .privileges(redfish::privileges::headActionInfo)
3486 .methods(boost::beast::http::verb::head)(std::bind_front(
3487 handleSystemCollectionResetActionHead, std::ref(app)));
Ed Tanous22d268c2022-05-19 09:39:07 -07003488 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003489 .privileges(redfish::privileges::getActionInfo)
Ed Tanousc1e219d2023-06-07 10:34:33 -07003490 .methods(boost::beast::http::verb::get)(std::bind_front(
3491 handleSystemCollectionResetActionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003492}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003493} // namespace redfish