blob: a38cc3af8c04b5ce412ba4d3dfa7bd1d37b60ca5 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070019#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080020#include "dbus_utility.hpp"
James Feistb49ac872019-05-21 15:12:01 -070021#include "health.hpp"
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -060022#include "hypervisor_system.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080023#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080024#include "pcie.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070025#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080026#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080027#include "registries/privilege_registry.hpp"
28#include "utils/dbus_utils.hpp"
29#include "utils/json_utils.hpp"
30#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070031#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080032
Ed Tanous9712f8a2018-09-21 13:38:49 -070033#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080034#include <boost/system/error_code.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070035#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020036#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050037
George Liu7a1dbc42022-12-07 16:03:22 +080038#include <array>
39#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080040#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020041
Ed Tanous1abe55e2018-09-05 08:30:59 -070042namespace redfish
43{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020044
Abhishek Patel5c3e9272021-06-24 10:11:33 -050045const static std::array<std::pair<std::string_view, std::string_view>, 2>
46 protocolToDBusForSystems{
47 {{"SSH", "obmc-console-ssh"}, {"IPMI", "phosphor-ipmi-net"}}};
48
Alpana Kumari9d3ae102019-04-12 06:49:32 -050049/**
50 * @brief Updates the Functional State of DIMMs
51 *
52 * @param[in] aResp Shared pointer for completing asynchronous calls
53 * @param[in] dimmState Dimm's Functional state, true/false
54 *
55 * @return None.
56 */
zhanghch058d1b46d2021-04-01 11:18:24 +080057inline void
58 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070059 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050060{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070061 BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050062
Gunnar Mills4e0453b2020-07-08 14:00:30 -050063 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050064 // Update STATE only if previous State was DISABLED and current Dimm is
65 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070066 const nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050067 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
68 if (prevMemSummary == "Disabled")
69 {
Ed Tanouse05aec52022-01-25 10:28:56 -080070 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050071 {
72 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
73 "Enabled";
74 }
75 }
76}
77
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050078/*
79 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
80 *
81 * @param[in] aResp Shared pointer for completing asynchronous calls
82 * @param[in] cpuPresenceState CPU present or not
83 *
84 * @return None.
85 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -070086inline void
87 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
88 bool isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050089{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070090 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050091
Ed Tanous55f79e62022-01-25 11:26:16 -080092 if (isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050093 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050094 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080095 aResp->res.jsonValue["ProcessorSummary"]["Count"];
Ed Tanous55f79e62022-01-25 11:26:16 -080096 auto* procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050097 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080098 if (procCountPtr != nullptr)
99 {
100 // shouldn't be possible to be nullptr
101 *procCountPtr += 1;
102 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500103 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500104}
105
106/*
107 * @brief Update "ProcessorSummary" "Status" "State" based on
108 * CPU Functional State
109 *
110 * @param[in] aResp Shared pointer for completing asynchronous calls
111 * @param[in] cpuFunctionalState is CPU functional true/false
112 *
113 * @return None.
114 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700115inline void
116 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
117 bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500118{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700119 BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500120
Ed Tanous02cad962022-06-30 16:50:15 -0700121 const nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500122 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
123
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500124 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500125 // Update STATE only if previous State was Non_Functional and current CPU is
126 // Functional.
127 if (prevProcState == "Disabled")
128 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800129 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500130 {
131 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
132 "Enabled";
133 }
134 }
135}
136
Ali Ahmed382d6472021-09-03 16:53:53 -0500137inline void getProcessorProperties(
138 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
139 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
140 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500141{
142
143 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
144
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200145 // TODO: Get Model
146
147 const uint16_t* coreCount = nullptr;
148
149 const bool success = sdbusplus::unpackPropertiesNoThrow(
150 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
151
152 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500153 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200154 messages::internalError(aResp->res);
155 return;
156 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500157
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200158 if (coreCount != nullptr)
159 {
160 nlohmann::json& coreCountJson =
161 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
162 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500163
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200164 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500165 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200166 coreCountJson = *coreCount;
167 }
168 else
169 {
170 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500171 }
172 }
173}
174
175/*
176 * @brief Get ProcessorSummary fields
177 *
178 * @param[in] aResp Shared pointer for completing asynchronous calls
179 * @param[in] service dbus service for Cpu Information
180 * @param[in] path dbus path for Cpu
181 *
182 * @return None.
183 */
184inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
185 const std::string& service,
186 const std::string& path)
187{
188
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800189 auto getCpuPresenceState = [aResp](const boost::system::error_code& ec3,
Ali Ahmed382d6472021-09-03 16:53:53 -0500190 const bool cpuPresenceCheck) {
191 if (ec3)
192 {
193 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
194 return;
195 }
196 modifyCpuPresenceState(aResp, cpuPresenceCheck);
197 };
198
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800199 auto getCpuFunctionalState = [aResp](const boost::system::error_code& ec3,
Ali Ahmed382d6472021-09-03 16:53:53 -0500200 const bool cpuFunctionalCheck) {
201 if (ec3)
202 {
203 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
204 return;
205 }
206 modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
207 };
208
209 // Get the Presence of CPU
210 sdbusplus::asio::getProperty<bool>(
211 *crow::connections::systemBus, service, path,
212 "xyz.openbmc_project.Inventory.Item", "Present",
213 std::move(getCpuPresenceState));
214
215 // Get the Functional State
216 sdbusplus::asio::getProperty<bool>(
217 *crow::connections::systemBus, service, path,
218 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
219 std::move(getCpuFunctionalState));
220
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200221 sdbusplus::asio::getAllProperties(
222 *crow::connections::systemBus, service, path,
223 "xyz.openbmc_project.Inventory.Item.Cpu",
Ali Ahmed03fbed92021-09-03 02:33:43 -0500224 [aResp, service,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800225 path](const boost::system::error_code& ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800226 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700227 if (ec2)
228 {
229 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
230 messages::internalError(aResp->res);
231 return;
232 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500233 getProcessorProperties(aResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200234 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500235}
236
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500237/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700238 * @brief Retrieves computer system properties over dbus
239 *
240 * @param[in] aResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500241 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700242 *
243 * @return None.
244 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700245inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800246 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700247 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700248{
Ed Tanous6c34de42018-08-29 13:37:36 -0700249 BMCWEB_LOG_DEBUG << "Get available system components.";
George Liue99073f2022-12-09 11:06:16 +0800250 constexpr std::array<std::string_view, 5> interfaces = {
251 "xyz.openbmc_project.Inventory.Decorator.Asset",
252 "xyz.openbmc_project.Inventory.Item.Cpu",
253 "xyz.openbmc_project.Inventory.Item.Dimm",
254 "xyz.openbmc_project.Inventory.Item.System",
255 "xyz.openbmc_project.Common.UUID",
256 };
257 dbus::utility::getSubTree(
258 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800259 [aResp,
George Liue99073f2022-12-09 11:06:16 +0800260 systemHealth](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800261 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700262 if (ec)
263 {
264 BMCWEB_LOG_DEBUG << "DBUS response error";
265 messages::internalError(aResp->res);
266 return;
267 }
268 // Iterate over all retrieved ObjectPaths.
269 for (const std::pair<
270 std::string,
271 std::vector<std::pair<std::string, std::vector<std::string>>>>&
272 object : subtree)
273 {
274 const std::string& path = object.first;
275 BMCWEB_LOG_DEBUG << "Got path: " << path;
276 const std::vector<std::pair<std::string, std::vector<std::string>>>&
277 connectionNames = object.second;
278 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700279 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700280 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700281 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700282
283 auto memoryHealth = std::make_shared<HealthPopulate>(
284 aResp, "/MemorySummary/Status"_json_pointer);
285
286 auto cpuHealth = std::make_shared<HealthPopulate>(
287 aResp, "/ProcessorSummary/Status"_json_pointer);
288
289 systemHealth->children.emplace_back(memoryHealth);
290 systemHealth->children.emplace_back(cpuHealth);
291
292 // This is not system, so check if it's cpu, dimm, UUID or
293 // BiosVer
294 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700295 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700296 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700297 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700298 if (interfaceName ==
299 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700300 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700301 BMCWEB_LOG_DEBUG
302 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500303
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200304 sdbusplus::asio::getAllProperties(
305 *crow::connections::systemBus, connection.first,
306 path, "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanous002d39b2022-05-31 08:59:27 -0700307 [aResp, service{connection.first},
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800308 path](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -0700309 const dbus::utility::DBusPropertiesMap&
310 properties) {
311 if (ec2)
312 {
313 BMCWEB_LOG_ERROR << "DBUS response error "
314 << ec2;
315 messages::internalError(aResp->res);
316 return;
317 }
318 BMCWEB_LOG_DEBUG << "Got " << properties.size()
319 << " Dimm properties.";
320
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200321 if (properties.empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700322 {
323 sdbusplus::asio::getProperty<bool>(
324 *crow::connections::systemBus, service,
325 path,
326 "xyz.openbmc_project.State."
327 "Decorator.OperationalStatus",
328 "Functional",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800329 [aResp](
330 const boost::system::error_code& ec3,
331 bool dimmState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700332 if (ec3)
333 {
334 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000335 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800336 return;
337 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700338 updateDimmProperties(aResp, dimmState);
339 });
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200340 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700341 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200342
343 const uint32_t* memorySizeInKB = nullptr;
344
345 const bool success =
346 sdbusplus::unpackPropertiesNoThrow(
347 dbus_utils::UnpackErrorPrinter(),
348 properties, "MemorySizeInKB",
349 memorySizeInKB);
350
351 if (!success)
352 {
353 messages::internalError(aResp->res);
354 return;
355 }
356
357 if (memorySizeInKB != nullptr)
358 {
359 nlohmann::json& totalMemory =
360 aResp->res
361 .jsonValue["MemorySummary"]
362 ["TotalSystemMemoryGiB"];
363 const uint64_t* preValue =
364 totalMemory.get_ptr<const uint64_t*>();
365 if (preValue == nullptr)
366 {
367 aResp->res
368 .jsonValue["MemorySummary"]
369 ["TotalSystemMemoryGiB"] =
370 *memorySizeInKB / (1024 * 1024);
371 }
372 else
373 {
374 aResp->res
375 .jsonValue["MemorySummary"]
376 ["TotalSystemMemoryGiB"] =
377 *memorySizeInKB / (1024 * 1024) +
378 *preValue;
379 }
380 aResp->res.jsonValue["MemorySummary"]["Status"]
381 ["State"] = "Enabled";
382 }
383 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700384
385 memoryHealth->inventory.emplace_back(path);
386 }
387 else if (interfaceName ==
388 "xyz.openbmc_project.Inventory.Item.Cpu")
389 {
390 BMCWEB_LOG_DEBUG
391 << "Found Cpu, now get its properties.";
392
393 getProcessorSummary(aResp, connection.first, path);
394
395 cpuHealth->inventory.emplace_back(path);
396 }
397 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
398 {
399 BMCWEB_LOG_DEBUG
400 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200401
402 sdbusplus::asio::getAllProperties(
403 *crow::connections::systemBus, connection.first,
404 path, "xyz.openbmc_project.Common.UUID",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800405 [aResp](const boost::system::error_code& ec3,
Ed Tanous002d39b2022-05-31 08:59:27 -0700406 const dbus::utility::DBusPropertiesMap&
407 properties) {
408 if (ec3)
409 {
410 BMCWEB_LOG_DEBUG << "DBUS response error "
411 << ec3;
412 messages::internalError(aResp->res);
413 return;
414 }
415 BMCWEB_LOG_DEBUG << "Got " << properties.size()
416 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700417
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200418 const std::string* uUID = nullptr;
419
420 const bool success =
421 sdbusplus::unpackPropertiesNoThrow(
422 dbus_utils::UnpackErrorPrinter(),
423 properties, "UUID", uUID);
424
425 if (!success)
426 {
427 messages::internalError(aResp->res);
428 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700429 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200430
431 if (uUID != nullptr)
432 {
433 std::string valueStr = *uUID;
434 if (valueStr.size() == 32)
435 {
436 valueStr.insert(8, 1, '-');
437 valueStr.insert(13, 1, '-');
438 valueStr.insert(18, 1, '-');
439 valueStr.insert(23, 1, '-');
440 }
441 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
442 aResp->res.jsonValue["UUID"] = valueStr;
443 }
444 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700445 }
446 else if (interfaceName ==
447 "xyz.openbmc_project.Inventory.Item.System")
448 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200449 sdbusplus::asio::getAllProperties(
450 *crow::connections::systemBus, connection.first,
451 path,
452 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800453 [aResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -0700454 const dbus::utility::DBusPropertiesMap&
455 propertiesList) {
456 if (ec2)
457 {
458 // doesn't have to include this
459 // interface
460 return;
461 }
462 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
463 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200464
465 const std::string* partNumber = nullptr;
466 const std::string* serialNumber = nullptr;
467 const std::string* manufacturer = nullptr;
468 const std::string* model = nullptr;
469 const std::string* subModel = nullptr;
470
471 const bool success =
472 sdbusplus::unpackPropertiesNoThrow(
473 dbus_utils::UnpackErrorPrinter(),
474 propertiesList, "PartNumber", partNumber,
475 "SerialNumber", serialNumber,
476 "Manufacturer", manufacturer, "Model",
477 model, "SubModel", subModel);
478
479 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700480 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200481 messages::internalError(aResp->res);
482 return;
483 }
484
485 if (partNumber != nullptr)
486 {
487 aResp->res.jsonValue["PartNumber"] =
488 *partNumber;
489 }
490
491 if (serialNumber != nullptr)
492 {
493 aResp->res.jsonValue["SerialNumber"] =
494 *serialNumber;
495 }
496
497 if (manufacturer != nullptr)
498 {
499 aResp->res.jsonValue["Manufacturer"] =
500 *manufacturer;
501 }
502
503 if (model != nullptr)
504 {
505 aResp->res.jsonValue["Model"] = *model;
506 }
507
508 if (subModel != nullptr)
509 {
510 aResp->res.jsonValue["SubModel"] = *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700511 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500512
Ed Tanous002d39b2022-05-31 08:59:27 -0700513 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700514 sw_util::populateSoftwareInformation(
515 aResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700516 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200517 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700518
Ed Tanous002d39b2022-05-31 08:59:27 -0700519 sdbusplus::asio::getProperty<std::string>(
520 *crow::connections::systemBus, connection.first,
521 path,
522 "xyz.openbmc_project.Inventory.Decorator."
523 "AssetTag",
524 "AssetTag",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800525 [aResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -0700526 const std::string& value) {
527 if (ec2)
528 {
529 // doesn't have to include this
530 // interface
531 return;
532 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700533
Ed Tanous002d39b2022-05-31 08:59:27 -0700534 aResp->res.jsonValue["AssetTag"] = value;
535 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700536 }
537 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200538 break;
Ed Tanous6c34de42018-08-29 13:37:36 -0700539 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700540 }
Ed Tanous66173382018-08-15 18:20:59 -0700541 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700542}
543
544/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700545 * @brief Retrieves host state properties over dbus
546 *
547 * @param[in] aResp Shared pointer for completing asynchronous calls.
548 *
549 * @return None.
550 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800551inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700552{
553 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700554 sdbusplus::asio::getProperty<std::string>(
555 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
556 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
557 "CurrentHostState",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800558 [aResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700559 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700560 if (ec)
561 {
562 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700563 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700564 // Service not available, no error, just don't return
565 // host state info
566 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700567 return;
568 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700569 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
570 messages::internalError(aResp->res);
571 return;
572 }
Ed Tanous66173382018-08-15 18:20:59 -0700573
Ed Tanous002d39b2022-05-31 08:59:27 -0700574 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
575 // Verify Host State
576 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
577 {
578 aResp->res.jsonValue["PowerState"] = "On";
579 aResp->res.jsonValue["Status"]["State"] = "Enabled";
580 }
581 else if (hostState ==
582 "xyz.openbmc_project.State.Host.HostState.Quiesced")
583 {
584 aResp->res.jsonValue["PowerState"] = "On";
585 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
586 }
587 else if (hostState ==
588 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
589 {
590 aResp->res.jsonValue["PowerState"] = "On";
591 aResp->res.jsonValue["Status"]["State"] = "InTest";
592 }
593 else if (
594 hostState ==
595 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
596 {
597 aResp->res.jsonValue["PowerState"] = "PoweringOn";
598 aResp->res.jsonValue["Status"]["State"] = "Starting";
599 }
600 else if (hostState ==
601 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
602 {
603 aResp->res.jsonValue["PowerState"] = "PoweringOff";
604 aResp->res.jsonValue["Status"]["State"] = "Disabled";
605 }
606 else
607 {
608 aResp->res.jsonValue["PowerState"] = "Off";
609 aResp->res.jsonValue["Status"]["State"] = "Disabled";
610 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700611 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700612}
613
614/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500615 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530616 *
617 * @param[in] dbusSource The boot source in DBUS speak.
618 *
619 * @return Returns as a string, the boot source in Redfish terms. If translation
620 * cannot be done, returns an empty string.
621 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000622inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530623{
624 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
625 {
626 return "None";
627 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700628 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530629 {
630 return "Hdd";
631 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700632 if (dbusSource ==
633 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530634 {
635 return "Cd";
636 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700637 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530638 {
639 return "Pxe";
640 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700641 if (dbusSource ==
642 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700643 {
644 return "Usb";
645 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700646 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530647}
648
649/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300650 * @brief Translates boot type DBUS property value to redfish.
651 *
652 * @param[in] dbusType The boot type in DBUS speak.
653 *
654 * @return Returns as a string, the boot type in Redfish terms. If translation
655 * cannot be done, returns an empty string.
656 */
657inline std::string dbusToRfBootType(const std::string& dbusType)
658{
659 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
660 {
661 return "Legacy";
662 }
663 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
664 {
665 return "UEFI";
666 }
667 return "";
668}
669
670/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500671 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530672 *
673 * @param[in] dbusMode The boot mode in DBUS speak.
674 *
675 * @return Returns as a string, the boot mode in Redfish terms. If translation
676 * cannot be done, returns an empty string.
677 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000678inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530679{
680 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
681 {
682 return "None";
683 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700684 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530685 {
686 return "Diags";
687 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700688 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530689 {
690 return "BiosSetup";
691 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700692 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530693}
694
695/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600696 * @brief Translates boot progress DBUS property value to redfish.
697 *
698 * @param[in] dbusBootProgress The boot progress in DBUS speak.
699 *
700 * @return Returns as a string, the boot progress in Redfish terms. If
701 * translation cannot be done, returns "None".
702 */
703inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
704{
705 // Now convert the D-Bus BootProgress to the appropriate Redfish
706 // enum
707 std::string rfBpLastState = "None";
708 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
709 "ProgressStages.Unspecified")
710 {
711 rfBpLastState = "None";
712 }
713 else if (dbusBootProgress ==
714 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715 "PrimaryProcInit")
716 {
717 rfBpLastState = "PrimaryProcessorInitializationStarted";
718 }
719 else if (dbusBootProgress ==
720 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721 "BusInit")
722 {
723 rfBpLastState = "BusInitializationStarted";
724 }
725 else if (dbusBootProgress ==
726 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727 "MemoryInit")
728 {
729 rfBpLastState = "MemoryInitializationStarted";
730 }
731 else if (dbusBootProgress ==
732 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733 "SecondaryProcInit")
734 {
735 rfBpLastState = "SecondaryProcessorInitializationStarted";
736 }
737 else if (dbusBootProgress ==
738 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739 "PCIInit")
740 {
741 rfBpLastState = "PCIResourceConfigStarted";
742 }
743 else if (dbusBootProgress ==
744 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745 "SystemSetup")
746 {
747 rfBpLastState = "SetupEntered";
748 }
749 else if (dbusBootProgress ==
750 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
751 "SystemInitComplete")
752 {
753 rfBpLastState = "SystemHardwareInitializationComplete";
754 }
755 else if (dbusBootProgress ==
756 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
757 "OSStart")
758 {
759 rfBpLastState = "OSBootStarted";
760 }
761 else if (dbusBootProgress ==
762 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
763 "OSRunning")
764 {
765 rfBpLastState = "OSRunning";
766 }
767 else
768 {
769 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
770 << dbusBootProgress;
771 // Just return the default
772 }
773 return rfBpLastState;
774}
775
776/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500777 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530778 *
779 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700780 * @param[out] bootSource The DBus source
781 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530782 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700783 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530784 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800785inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500786 const std::string& rfSource,
787 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530788{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300789 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
790 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700791
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530792 if (rfSource == "None")
793 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700794 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530795 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700796 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530797 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700798 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
799 }
800 else if (rfSource == "Hdd")
801 {
802 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
803 }
804 else if (rfSource == "Diags")
805 {
806 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
807 }
808 else if (rfSource == "Cd")
809 {
810 bootSource =
811 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
812 }
813 else if (rfSource == "BiosSetup")
814 {
815 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530816 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700817 else if (rfSource == "Usb")
818 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700819 bootSource =
820 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700821 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530822 else
823 {
George Liu0fda0f12021-11-16 10:06:17 +0800824 BMCWEB_LOG_DEBUG
825 << "Invalid property value for BootSourceOverrideTarget: "
826 << bootSource;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700827 messages::propertyValueNotInList(aResp->res, rfSource,
828 "BootSourceTargetOverride");
829 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530830 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700831 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530832}
Ali Ahmed19817712021-06-29 17:01:52 -0500833
Andrew Geissler978b8802020-11-19 13:36:40 -0600834/**
835 * @brief Retrieves boot progress of the system
836 *
837 * @param[in] aResp Shared pointer for generating response message.
838 *
839 * @return None.
840 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800841inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600842{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700843 sdbusplus::asio::getProperty<std::string>(
844 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
845 "/xyz/openbmc_project/state/host0",
846 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800847 [aResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700848 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700849 if (ec)
850 {
851 // BootProgress is an optional object so just do nothing if
852 // not found
853 return;
854 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600855
Ed Tanous002d39b2022-05-31 08:59:27 -0700856 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600857
Ed Tanous002d39b2022-05-31 08:59:27 -0700858 aResp->res.jsonValue["BootProgress"]["LastState"] =
859 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700860 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600861}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530862
863/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000864 * @brief Retrieves boot progress Last Update of the system
865 *
866 * @param[in] aResp Shared pointer for generating response message.
867 *
868 * @return None.
869 */
870inline void getBootProgressLastStateTime(
871 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
872{
873 sdbusplus::asio::getProperty<uint64_t>(
874 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
875 "/xyz/openbmc_project/state/host0",
876 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800877 [aResp](const boost::system::error_code& ec,
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000878 const uint64_t lastStateTime) {
879 if (ec)
880 {
881 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
882 return;
883 }
884
885 // BootProgressLastUpdate is the last time the BootProgress property
886 // was updated. The time is the Epoch time, number of microseconds
887 // since 1 Jan 1970 00::00::00 UTC."
888 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
889 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
890
891 // Convert to ISO 8601 standard
892 aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
893 redfish::time_utils::getDateTimeUintUs(lastStateTime);
894 });
895}
896
897/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300898 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300899 *
900 * @param[in] aResp Shared pointer for generating response message.
901 *
902 * @return None.
903 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300904
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300905inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300906{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700907 sdbusplus::asio::getProperty<std::string>(
908 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
909 "/xyz/openbmc_project/control/host0/boot",
910 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800911 [aResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700912 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700913 if (ec)
914 {
915 // not an error, don't have to have the interface
916 return;
917 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300918
Ed Tanous002d39b2022-05-31 08:59:27 -0700919 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300920
Ed Tanous002d39b2022-05-31 08:59:27 -0700921 aResp->res.jsonValue["Boot"]
922 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700923 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300924
Ed Tanous002d39b2022-05-31 08:59:27 -0700925 auto rfType = dbusToRfBootType(bootType);
926 if (rfType.empty())
927 {
928 messages::internalError(aResp->res);
929 return;
930 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300931
Ed Tanous002d39b2022-05-31 08:59:27 -0700932 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700933 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300934}
935
936/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300937 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530938 *
939 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530940 *
941 * @return None.
942 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300943
944inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530945{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700946 sdbusplus::asio::getProperty<std::string>(
947 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
948 "/xyz/openbmc_project/control/host0/boot",
949 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800950 [aResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700951 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700952 if (ec)
953 {
954 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
955 messages::internalError(aResp->res);
956 return;
957 }
958
959 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
960
961 aResp->res
962 .jsonValue["Boot"]
963 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
964 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
965
966 if (bootModeStr !=
967 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
968 {
969 auto rfMode = dbusToRfBootMode(bootModeStr);
970 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530971 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700972 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
973 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700975 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700976 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530977}
978
979/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300980 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530981 *
982 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530983 *
984 * @return None.
985 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300986
987inline void
988 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530989{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700990 sdbusplus::asio::getProperty<std::string>(
991 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
992 "/xyz/openbmc_project/control/host0/boot",
993 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800994 [aResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700995 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700996 if (ec)
997 {
998 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +0000999 if (ec.value() == boost::asio::error::host_unreachable)
1000 {
1001 return;
1002 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001003 messages::internalError(aResp->res);
1004 return;
1005 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301006
Ed Tanous002d39b2022-05-31 08:59:27 -07001007 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301008
Ed Tanous002d39b2022-05-31 08:59:27 -07001009 auto rfSource = dbusToRfBootSource(bootSourceStr);
1010 if (!rfSource.empty())
1011 {
1012 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1013 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001014
Ed Tanous002d39b2022-05-31 08:59:27 -07001015 // Get BootMode as BootSourceOverrideTarget is constructed
1016 // from both BootSource and BootMode
1017 getBootOverrideMode(aResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001018 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301019}
1020
1021/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001022 * @brief This functions abstracts all the logic behind getting a
1023 * "BootSourceOverrideEnabled" property from an overall boot override enable
1024 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301025 *
1026 * @param[in] aResp Shared pointer for generating response message.
1027 *
1028 * @return None.
1029 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001031inline void
1032 processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1033 const bool bootOverrideEnableSetting)
1034{
1035 if (!bootOverrideEnableSetting)
1036 {
1037 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1038 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"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001043 sdbusplus::asio::getProperty<bool>(
1044 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1045 "/xyz/openbmc_project/control/host0/boot/one_time",
1046 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001047 [aResp](const boost::system::error_code& ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001048 if (ec)
1049 {
1050 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1051 messages::internalError(aResp->res);
1052 return;
1053 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301054
Ed Tanous002d39b2022-05-31 08:59:27 -07001055 if (oneTimeSetting)
1056 {
1057 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1058 }
1059 else
1060 {
1061 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1062 "Continuous";
1063 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001064 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301065}
1066
1067/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001068 * @brief Retrieves boot override enable over DBUS
1069 *
1070 * @param[in] aResp Shared pointer for generating response message.
1071 *
1072 * @return None.
1073 */
1074
1075inline void
1076 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1077{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001078 sdbusplus::asio::getProperty<bool>(
1079 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1080 "/xyz/openbmc_project/control/host0/boot",
1081 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001082 [aResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001083 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001084 if (ec)
1085 {
1086 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001087 if (ec.value() == boost::asio::error::host_unreachable)
1088 {
1089 return;
1090 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001091 messages::internalError(aResp->res);
1092 return;
1093 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001094
Ed Tanous002d39b2022-05-31 08:59:27 -07001095 processBootOverrideEnable(aResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001096 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001097}
1098
1099/**
1100 * @brief Retrieves boot source override properties
1101 *
1102 * @param[in] aResp Shared pointer for generating response message.
1103 *
1104 * @return None.
1105 */
1106inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1107{
1108 BMCWEB_LOG_DEBUG << "Get boot information.";
1109
1110 getBootOverrideSource(aResp);
1111 getBootOverrideType(aResp);
1112 getBootOverrideEnable(aResp);
1113}
1114
1115/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001116 * @brief Retrieves the Last Reset Time
1117 *
1118 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1119 * and power off. Even though this is the "system" Redfish object look at the
1120 * chassis D-Bus interface for the LastStateChangeTime since this has the
1121 * last power operation time.
1122 *
1123 * @param[in] aResp Shared pointer for generating response message.
1124 *
1125 * @return None.
1126 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001127inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001128{
1129 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1130
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001131 sdbusplus::asio::getProperty<uint64_t>(
1132 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1133 "/xyz/openbmc_project/state/chassis0",
1134 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001135 [aResp](const boost::system::error_code& ec, uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001136 if (ec)
1137 {
1138 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1139 return;
1140 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001141
Ed Tanous002d39b2022-05-31 08:59:27 -07001142 // LastStateChangeTime is epoch time, in milliseconds
1143 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1144 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001145
Ed Tanous002d39b2022-05-31 08:59:27 -07001146 // Convert to ISO 8601 standard
1147 aResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001148 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001149 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001150}
1151
1152/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001153 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1154 *
1155 * @param[in] aResp Shared pointer for generating response message.
1156 *
1157 * @return None.
1158 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001159inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001160{
1161 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1162
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001163 sdbusplus::asio::getProperty<bool>(
1164 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1165 "/xyz/openbmc_project/control/host0/auto_reboot",
1166 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001167 [aResp](const boost::system::error_code& ec, bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001168 if (ec)
1169 {
1170 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1171 return;
1172 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001173
Ed Tanous002d39b2022-05-31 08:59:27 -07001174 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1175 if (autoRebootEnabled)
1176 {
1177 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1178 "RetryAttempts";
1179 // If AutomaticRetry (AutoReboot) is enabled see how many
1180 // attempts are left
1181 sdbusplus::asio::getProperty<uint32_t>(
1182 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1183 "/xyz/openbmc_project/state/host0",
1184 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1185 "AttemptsLeft",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001186 [aResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07001187 const uint32_t autoRebootAttemptsLeft) {
1188 if (ec2)
1189 {
1190 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
1191 return;
1192 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001193
Ed Tanous002d39b2022-05-31 08:59:27 -07001194 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1195 << autoRebootAttemptsLeft;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001196
Ed Tanous002d39b2022-05-31 08:59:27 -07001197 aResp->res
1198 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1199 autoRebootAttemptsLeft;
1200 });
1201 }
1202 else
1203 {
1204 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
1205 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001206
Ed Tanous002d39b2022-05-31 08:59:27 -07001207 // Not on D-Bus. Hardcoded here:
1208 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1209 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001210
Ed Tanous002d39b2022-05-31 08:59:27 -07001211 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1212 // and RetryAttempts. OpenBMC only supports Disabled and
1213 // RetryAttempts.
1214 aResp->res.jsonValue["Boot"]
1215 ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
1216 "Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001217 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001218}
1219
1220/**
George Liuc6a620f2020-04-10 17:18:11 +08001221 * @brief Retrieves power restore policy over DBUS.
1222 *
1223 * @param[in] aResp Shared pointer for generating response message.
1224 *
1225 * @return None.
1226 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001227inline void
1228 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001229{
1230 BMCWEB_LOG_DEBUG << "Get power restore policy";
1231
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001232 sdbusplus::asio::getProperty<std::string>(
1233 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1234 "/xyz/openbmc_project/control/host0/power_restore_policy",
1235 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001236 [aResp](const boost::system::error_code& ec,
1237 const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001238 if (ec)
1239 {
1240 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1241 return;
1242 }
George Liuc6a620f2020-04-10 17:18:11 +08001243
Ed Tanous002d39b2022-05-31 08:59:27 -07001244 const boost::container::flat_map<std::string, std::string> policyMaps = {
1245 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1246 "AlwaysOn"},
1247 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1248 "AlwaysOff"},
1249 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1250 "LastState"},
1251 // Return `AlwaysOff` when power restore policy set to "None"
1252 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
1253 "AlwaysOff"}};
George Liuc6a620f2020-04-10 17:18:11 +08001254
Ed Tanous002d39b2022-05-31 08:59:27 -07001255 auto policyMapsIt = policyMaps.find(policy);
1256 if (policyMapsIt == policyMaps.end())
1257 {
1258 messages::internalError(aResp->res);
1259 return;
1260 }
George Liuc6a620f2020-04-10 17:18:11 +08001261
Ed Tanous002d39b2022-05-31 08:59:27 -07001262 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001263 });
George Liuc6a620f2020-04-10 17:18:11 +08001264}
1265
1266/**
Ali Ahmed19817712021-06-29 17:01:52 -05001267 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1268 * TPM is required for booting the host.
1269 *
1270 * @param[in] aResp Shared pointer for generating response message.
1271 *
1272 * @return None.
1273 */
1274inline void getTrustedModuleRequiredToBoot(
1275 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1276{
1277 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001278 constexpr std::array<std::string_view, 1> interfaces = {
1279 "xyz.openbmc_project.Control.TPM.Policy"};
1280 dbus::utility::getSubTree(
1281 "/", 0, interfaces,
1282 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001283 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001284 if (ec)
1285 {
1286 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1287 << ec;
1288 // This is an optional D-Bus object so just return if
1289 // error occurs
1290 return;
1291 }
1292 if (subtree.empty())
1293 {
1294 // As noted above, this is an optional interface so just return
1295 // if there is no instance found
1296 return;
1297 }
1298
1299 /* When there is more than one TPMEnable object... */
1300 if (subtree.size() > 1)
1301 {
1302 BMCWEB_LOG_DEBUG
1303 << "DBUS response has more than 1 TPM Enable object:"
1304 << subtree.size();
1305 // Throw an internal Error and return
1306 messages::internalError(aResp->res);
1307 return;
1308 }
1309
1310 // Make sure the Dbus response map has a service and objectPath
1311 // field
1312 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1313 {
1314 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1315 messages::internalError(aResp->res);
1316 return;
1317 }
1318
1319 const std::string& path = subtree[0].first;
1320 const std::string& serv = subtree[0].second.begin()->first;
1321
1322 // Valid TPM Enable object found, now reading the current value
1323 sdbusplus::asio::getProperty<bool>(
1324 *crow::connections::systemBus, serv, path,
1325 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001326 [aResp](const boost::system::error_code& ec2, bool tpmRequired) {
Ed Tanous8a592812022-06-04 09:06:59 -07001327 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001328 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001329 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001330 << ec2;
Ali Ahmed19817712021-06-29 17:01:52 -05001331 messages::internalError(aResp->res);
1332 return;
1333 }
1334
Ed Tanous002d39b2022-05-31 08:59:27 -07001335 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001336 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001337 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1338 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001339 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001340 else
1341 {
1342 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1343 "Disabled";
1344 }
1345 });
George Liue99073f2022-12-09 11:06:16 +08001346 });
Ali Ahmed19817712021-06-29 17:01:52 -05001347}
1348
1349/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001350 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1351 * TPM is required for booting the host.
1352 *
1353 * @param[in] aResp Shared pointer for generating response message.
1354 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1355 *
1356 * @return None.
1357 */
1358inline void setTrustedModuleRequiredToBoot(
1359 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
1360{
1361 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001362 constexpr std::array<std::string_view, 1> interfaces = {
1363 "xyz.openbmc_project.Control.TPM.Policy"};
1364 dbus::utility::getSubTree(
1365 "/", 0, interfaces,
1366 [aResp,
1367 tpmRequired](const boost::system::error_code& ec,
1368 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001369 if (ec)
1370 {
1371 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1372 << ec;
1373 messages::internalError(aResp->res);
1374 return;
1375 }
1376 if (subtree.empty())
1377 {
1378 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
1379 "TrustedModuleRequiredToBoot");
1380 return;
1381 }
1382
1383 /* When there is more than one TPMEnable object... */
1384 if (subtree.size() > 1)
1385 {
1386 BMCWEB_LOG_DEBUG
1387 << "DBUS response has more than 1 TPM Enable object:"
1388 << subtree.size();
1389 // Throw an internal Error and return
1390 messages::internalError(aResp->res);
1391 return;
1392 }
1393
1394 // Make sure the Dbus response map has a service and objectPath
1395 // field
1396 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1397 {
1398 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1399 messages::internalError(aResp->res);
1400 return;
1401 }
1402
1403 const std::string& path = subtree[0].first;
1404 const std::string& serv = subtree[0].second.begin()->first;
1405
1406 if (serv.empty())
1407 {
1408 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1409 messages::internalError(aResp->res);
1410 return;
1411 }
1412
1413 // Valid TPM Enable object found, now setting the value
1414 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001415 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001416 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001417 {
1418 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001419 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001420 << ec2;
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001421 messages::internalError(aResp->res);
1422 return;
1423 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001424 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1425 },
1426 serv, path, "org.freedesktop.DBus.Properties", "Set",
1427 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1428 dbus::utility::DbusVariantType(tpmRequired));
George Liue99073f2022-12-09 11:06:16 +08001429 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001430}
1431
1432/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301433 * @brief Sets boot properties into DBUS object(s).
1434 *
1435 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001436 * @param[in] bootType The boot type to set.
1437 * @return Integer error code.
1438 */
1439inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001440 const std::optional<std::string>& bootType)
1441{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001442 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001443
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001444 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001445 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001446 return;
1447 }
1448
1449 // Source target specified
1450 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1451 // Figure out which DBUS interface and property to use
1452 if (*bootType == "Legacy")
1453 {
1454 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1455 }
1456 else if (*bootType == "UEFI")
1457 {
1458 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1459 }
1460 else
1461 {
1462 BMCWEB_LOG_DEBUG << "Invalid property value for "
1463 "BootSourceOverrideMode: "
1464 << *bootType;
1465 messages::propertyValueNotInList(aResp->res, *bootType,
1466 "BootSourceOverrideMode");
1467 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001468 }
1469
1470 // Act on validated parameters
1471 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1472
1473 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001474 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001475 if (ec)
1476 {
1477 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1478 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001479 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001480 messages::resourceNotFound(aResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001481 return;
1482 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001483 messages::internalError(aResp->res);
1484 return;
1485 }
1486 BMCWEB_LOG_DEBUG << "Boot type update done.";
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001487 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001488 "xyz.openbmc_project.Settings",
1489 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001490 "org.freedesktop.DBus.Properties", "Set",
1491 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001492 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001493}
1494
1495/**
1496 * @brief Sets boot properties into DBUS object(s).
1497 *
1498 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001499 * @param[in] bootType The boot type to set.
1500 * @return Integer error code.
1501 */
1502inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1503 const std::optional<std::string>& bootEnable)
1504{
1505 if (!bootEnable)
1506 {
1507 return;
1508 }
1509 // Source target specified
1510 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1511
1512 bool bootOverrideEnable = false;
1513 bool bootOverridePersistent = false;
1514 // Figure out which DBUS interface and property to use
1515 if (*bootEnable == "Disabled")
1516 {
1517 bootOverrideEnable = false;
1518 }
1519 else if (*bootEnable == "Once")
1520 {
1521 bootOverrideEnable = true;
1522 bootOverridePersistent = false;
1523 }
1524 else if (*bootEnable == "Continuous")
1525 {
1526 bootOverrideEnable = true;
1527 bootOverridePersistent = true;
1528 }
1529 else
1530 {
George Liu0fda0f12021-11-16 10:06:17 +08001531 BMCWEB_LOG_DEBUG
1532 << "Invalid property value for BootSourceOverrideEnabled: "
1533 << *bootEnable;
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001534 messages::propertyValueNotInList(aResp->res, *bootEnable,
1535 "BootSourceOverrideEnabled");
1536 return;
1537 }
1538
1539 // Act on validated parameters
1540 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1541
1542 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001543 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07001544 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001545 {
Ed Tanous8a592812022-06-04 09:06:59 -07001546 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07001547 messages::internalError(aResp->res);
1548 return;
1549 }
1550 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001551 },
1552 "xyz.openbmc_project.Settings",
1553 "/xyz/openbmc_project/control/host0/boot",
1554 "org.freedesktop.DBus.Properties", "Set",
1555 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001556 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001557
1558 if (!bootOverrideEnable)
1559 {
1560 return;
1561 }
1562
1563 // In case boot override is enabled we need to set correct value for the
1564 // 'one_time' enable DBus interface
1565 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1566 << bootOverridePersistent;
1567
1568 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001569 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001570 if (ec)
1571 {
1572 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1573 messages::internalError(aResp->res);
1574 return;
1575 }
1576 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001577 },
1578 "xyz.openbmc_project.Settings",
1579 "/xyz/openbmc_project/control/host0/boot/one_time",
1580 "org.freedesktop.DBus.Properties", "Set",
1581 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001582 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001583}
1584
1585/**
1586 * @brief Sets boot properties into DBUS object(s).
1587 *
1588 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301589 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301590 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001591 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301592 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001593inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001594 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301595{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001596 std::string bootSourceStr;
1597 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001598
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001599 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301600 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001601 return;
1602 }
1603
1604 // Source target specified
1605 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1606 // Figure out which DBUS interface and property to use
Ed Tanouse662eae2022-01-25 10:39:19 -08001607 if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1608 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001609 {
1610 BMCWEB_LOG_DEBUG
1611 << "Invalid property value for BootSourceOverrideTarget: "
1612 << *bootSource;
1613 messages::propertyValueNotInList(aResp->res, *bootSource,
1614 "BootSourceTargetOverride");
1615 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001616 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301617
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001618 // Act on validated parameters
1619 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1620 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001621
1622 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001623 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001624 if (ec)
1625 {
1626 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1627 messages::internalError(aResp->res);
1628 return;
1629 }
1630 BMCWEB_LOG_DEBUG << "Boot source update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001631 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001632 "xyz.openbmc_project.Settings",
1633 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001634 "org.freedesktop.DBus.Properties", "Set",
1635 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001636 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001637
1638 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001639 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001640 if (ec)
1641 {
1642 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1643 messages::internalError(aResp->res);
1644 return;
1645 }
1646 BMCWEB_LOG_DEBUG << "Boot mode update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001647 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001648 "xyz.openbmc_project.Settings",
1649 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001650 "org.freedesktop.DBus.Properties", "Set",
1651 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001652 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001653}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001654
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001655/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001656 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301657 *
1658 * @param[in] aResp Shared pointer for generating response message.
1659 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001660 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301661 * @param[in] bootEnable The boot override enable from incoming RF request.
1662 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001663 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301664 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001665
1666inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1667 const std::optional<std::string>& bootSource,
1668 const std::optional<std::string>& bootType,
1669 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301670{
1671 BMCWEB_LOG_DEBUG << "Set boot information.";
1672
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001673 setBootModeOrSource(aResp, bootSource);
1674 setBootType(aResp, bootType);
1675 setBootEnable(aResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301676}
1677
George Liuc6a620f2020-04-10 17:18:11 +08001678/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001679 * @brief Sets AssetTag
1680 *
1681 * @param[in] aResp Shared pointer for generating response message.
1682 * @param[in] assetTag "AssetTag" from request.
1683 *
1684 * @return None.
1685 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001686inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001687 const std::string& assetTag)
1688{
George Liue99073f2022-12-09 11:06:16 +08001689 constexpr std::array<std::string_view, 1> interfaces = {
1690 "xyz.openbmc_project.Inventory.Item.System"};
1691 dbus::utility::getSubTree(
1692 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001693 [aResp,
George Liue99073f2022-12-09 11:06:16 +08001694 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001695 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001696 if (ec)
1697 {
1698 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1699 messages::internalError(aResp->res);
1700 return;
1701 }
1702 if (subtree.empty())
1703 {
1704 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1705 messages::internalError(aResp->res);
1706 return;
1707 }
1708 // Assume only 1 system D-Bus object
1709 // Throw an error if there is more than 1
1710 if (subtree.size() > 1)
1711 {
1712 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1713 messages::internalError(aResp->res);
1714 return;
1715 }
1716 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1717 {
1718 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1719 messages::internalError(aResp->res);
1720 return;
1721 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001722
Ed Tanous002d39b2022-05-31 08:59:27 -07001723 const std::string& path = subtree[0].first;
1724 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001725
Ed Tanous002d39b2022-05-31 08:59:27 -07001726 if (service.empty())
1727 {
1728 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1729 messages::internalError(aResp->res);
1730 return;
1731 }
1732
1733 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001734 [aResp](const boost::system::error_code& ec2) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001735 if (ec2)
Gunnar Mills98e386e2020-10-30 14:58:09 -05001736 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001737 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1738 << ec2;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001739 messages::internalError(aResp->res);
1740 return;
1741 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001742 },
1743 service, path, "org.freedesktop.DBus.Properties", "Set",
1744 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1745 dbus::utility::DbusVariantType(assetTag));
George Liue99073f2022-12-09 11:06:16 +08001746 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001747}
1748
1749/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001750 * @brief Sets automaticRetry (Auto Reboot)
1751 *
1752 * @param[in] aResp Shared pointer for generating response message.
1753 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1754 *
1755 * @return None.
1756 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001757inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -07001758 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001759{
1760 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1761
1762 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001763 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001764
1765 if (automaticRetryConfig == "Disabled")
1766 {
1767 autoRebootEnabled = false;
1768 }
1769 else if (automaticRetryConfig == "RetryAttempts")
1770 {
1771 autoRebootEnabled = true;
1772 }
1773 else
1774 {
George Liu0fda0f12021-11-16 10:06:17 +08001775 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001776 << automaticRetryConfig;
1777 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1778 "AutomaticRetryConfig");
1779 return;
1780 }
1781
1782 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001783 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001784 if (ec)
1785 {
1786 messages::internalError(aResp->res);
1787 return;
1788 }
Gunnar Mills69f35302020-05-17 16:06:31 -05001789 },
1790 "xyz.openbmc_project.Settings",
1791 "/xyz/openbmc_project/control/host0/auto_reboot",
1792 "org.freedesktop.DBus.Properties", "Set",
1793 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous168e20c2021-12-13 14:39:53 -08001794 dbus::utility::DbusVariantType(autoRebootEnabled));
Gunnar Mills69f35302020-05-17 16:06:31 -05001795}
1796
1797/**
George Liuc6a620f2020-04-10 17:18:11 +08001798 * @brief Sets power restore policy properties.
1799 *
1800 * @param[in] aResp Shared pointer for generating response message.
1801 * @param[in] policy power restore policy properties from request.
1802 *
1803 * @return None.
1804 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001805inline void
1806 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1807 const std::string& policy)
George Liuc6a620f2020-04-10 17:18:11 +08001808{
1809 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1810
1811 const boost::container::flat_map<std::string, std::string> policyMaps = {
George Liu0fda0f12021-11-16 10:06:17 +08001812 {"AlwaysOn",
1813 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
1814 {"AlwaysOff",
1815 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
1816 {"LastState",
1817 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
George Liuc6a620f2020-04-10 17:18:11 +08001818
1819 std::string powerRestorPolicy;
1820
Gunnar Mills4e69c902021-01-05 19:50:11 -06001821 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001822 if (policyMapsIt == policyMaps.end())
1823 {
Gunnar Mills4e69c902021-01-05 19:50:11 -06001824 messages::propertyValueNotInList(aResp->res, policy,
1825 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001826 return;
1827 }
1828
1829 powerRestorPolicy = policyMapsIt->second;
1830
1831 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001832 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001833 if (ec)
1834 {
1835 messages::internalError(aResp->res);
1836 return;
1837 }
George Liuc6a620f2020-04-10 17:18:11 +08001838 },
1839 "xyz.openbmc_project.Settings",
1840 "/xyz/openbmc_project/control/host0/power_restore_policy",
1841 "org.freedesktop.DBus.Properties", "Set",
1842 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous168e20c2021-12-13 14:39:53 -08001843 dbus::utility::DbusVariantType(powerRestorPolicy));
George Liuc6a620f2020-04-10 17:18:11 +08001844}
1845
AppaRao Pulia6349912019-10-18 17:16:08 +05301846#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1847/**
1848 * @brief Retrieves provisioning status
1849 *
1850 * @param[in] aResp Shared pointer for completing asynchronous calls.
1851 *
1852 * @return None.
1853 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001854inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301855{
1856 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001857 sdbusplus::asio::getAllProperties(
1858 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1859 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08001860 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001861 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001862 nlohmann::json& oemPFR =
1863 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1864 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1865 "#OemComputerSystem.OpenBmc";
1866 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07001867
Ed Tanous002d39b2022-05-31 08:59:27 -07001868 if (ec)
1869 {
1870 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1871 // not an error, don't have to have the interface
1872 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1873 return;
1874 }
1875
1876 const bool* provState = nullptr;
1877 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001878
1879 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08001880 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
1881 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001882
1883 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07001884 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001885 messages::internalError(aResp->res);
1886 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07001887 }
AppaRao Pulia6349912019-10-18 17:16:08 +05301888
Ed Tanous002d39b2022-05-31 08:59:27 -07001889 if ((provState == nullptr) || (lockState == nullptr))
1890 {
1891 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1892 messages::internalError(aResp->res);
1893 return;
1894 }
AppaRao Pulia6349912019-10-18 17:16:08 +05301895
Ed Tanous002d39b2022-05-31 08:59:27 -07001896 if (*provState == true)
1897 {
1898 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05301899 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001900 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05301901 }
1902 else
1903 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001904 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05301905 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001906 }
1907 else
1908 {
1909 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1910 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001911 });
AppaRao Pulia6349912019-10-18 17:16:08 +05301912}
1913#endif
1914
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301915/**
Chris Cain3a2d04242021-05-28 16:57:10 -05001916 * @brief Translate the PowerMode to a response message.
1917 *
1918 * @param[in] aResp Shared pointer for generating response message.
1919 * @param[in] modeValue PowerMode value to be translated
1920 *
1921 * @return None.
1922 */
1923inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1924 const std::string& modeValue)
1925{
George Liu0fda0f12021-11-16 10:06:17 +08001926 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05001927 {
1928 aResp->res.jsonValue["PowerMode"] = "Static";
1929 }
George Liu0fda0f12021-11-16 10:06:17 +08001930 else if (
1931 modeValue ==
1932 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05001933 {
1934 aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
1935 }
George Liu0fda0f12021-11-16 10:06:17 +08001936 else if (modeValue ==
1937 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05001938 {
1939 aResp->res.jsonValue["PowerMode"] = "PowerSaving";
1940 }
George Liu0fda0f12021-11-16 10:06:17 +08001941 else if (modeValue ==
1942 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05001943 {
1944 aResp->res.jsonValue["PowerMode"] = "OEM";
1945 }
1946 else
1947 {
1948 // Any other values would be invalid
1949 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
1950 messages::internalError(aResp->res);
1951 }
1952}
1953
1954/**
1955 * @brief Retrieves system power mode
1956 *
1957 * @param[in] aResp Shared pointer for generating response message.
1958 *
1959 * @return None.
1960 */
1961inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1962{
1963 BMCWEB_LOG_DEBUG << "Get power mode.";
1964
1965 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08001966 constexpr std::array<std::string_view, 1> interfaces = {
1967 "xyz.openbmc_project.Control.Power.Mode"};
1968 dbus::utility::getSubTree(
1969 "/", 0, interfaces,
1970 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001971 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001972 if (ec)
1973 {
1974 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1975 << ec;
1976 // This is an optional D-Bus object so just return if
1977 // error occurs
1978 return;
1979 }
1980 if (subtree.empty())
1981 {
1982 // As noted above, this is an optional interface so just return
1983 // if there is no instance found
1984 return;
1985 }
1986 if (subtree.size() > 1)
1987 {
1988 // More then one PowerMode object is not supported and is an
1989 // error
1990 BMCWEB_LOG_DEBUG
1991 << "Found more than 1 system D-Bus Power.Mode objects: "
1992 << subtree.size();
1993 messages::internalError(aResp->res);
1994 return;
1995 }
1996 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
1997 {
1998 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
1999 messages::internalError(aResp->res);
2000 return;
2001 }
2002 const std::string& path = subtree[0].first;
2003 const std::string& service = subtree[0].second.begin()->first;
2004 if (service.empty())
2005 {
2006 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2007 messages::internalError(aResp->res);
2008 return;
2009 }
2010 // Valid Power Mode object found, now read the current value
2011 sdbusplus::asio::getProperty<std::string>(
2012 *crow::connections::systemBus, service, path,
2013 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002014 [aResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002015 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002016 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002017 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002018 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002019 << ec2;
Chris Cain3a2d04242021-05-28 16:57:10 -05002020 messages::internalError(aResp->res);
2021 return;
2022 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002023
Ed Tanous002d39b2022-05-31 08:59:27 -07002024 aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2025 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002026
Ed Tanous002d39b2022-05-31 08:59:27 -07002027 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2028 translatePowerMode(aResp, pmode);
2029 });
George Liue99073f2022-12-09 11:06:16 +08002030 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002031}
2032
2033/**
2034 * @brief Validate the specified mode is valid and return the PowerMode
2035 * name associated with that string
2036 *
2037 * @param[in] aResp Shared pointer for generating response message.
2038 * @param[in] modeString String representing the desired PowerMode
2039 *
2040 * @return PowerMode value or empty string if mode is not valid
2041 */
2042inline std::string
2043 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2044 const std::string& modeString)
2045{
2046 std::string mode;
2047
2048 if (modeString == "Static")
2049 {
2050 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2051 }
2052 else if (modeString == "MaximumPerformance")
2053 {
George Liu0fda0f12021-11-16 10:06:17 +08002054 mode =
2055 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002056 }
2057 else if (modeString == "PowerSaving")
2058 {
2059 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2060 }
2061 else
2062 {
2063 messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
2064 }
2065 return mode;
2066}
2067
2068/**
2069 * @brief Sets system power mode.
2070 *
2071 * @param[in] aResp Shared pointer for generating response message.
2072 * @param[in] pmode System power mode from request.
2073 *
2074 * @return None.
2075 */
2076inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2077 const std::string& pmode)
2078{
2079 BMCWEB_LOG_DEBUG << "Set power mode.";
2080
2081 std::string powerMode = validatePowerMode(aResp, pmode);
2082 if (powerMode.empty())
2083 {
2084 return;
2085 }
2086
2087 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002088 constexpr std::array<std::string_view, 1> interfaces = {
2089 "xyz.openbmc_project.Control.Power.Mode"};
2090 dbus::utility::getSubTree(
2091 "/", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002092 [aResp,
George Liue99073f2022-12-09 11:06:16 +08002093 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002094 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002095 if (ec)
2096 {
2097 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2098 << ec;
2099 // This is an optional D-Bus object, but user attempted to patch
2100 messages::internalError(aResp->res);
2101 return;
2102 }
2103 if (subtree.empty())
2104 {
2105 // This is an optional D-Bus object, but user attempted to patch
2106 messages::resourceNotFound(aResp->res, "ComputerSystem",
2107 "PowerMode");
2108 return;
2109 }
2110 if (subtree.size() > 1)
2111 {
2112 // More then one PowerMode object is not supported and is an
2113 // error
2114 BMCWEB_LOG_DEBUG
2115 << "Found more than 1 system D-Bus Power.Mode objects: "
2116 << subtree.size();
2117 messages::internalError(aResp->res);
2118 return;
2119 }
2120 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2121 {
2122 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2123 messages::internalError(aResp->res);
2124 return;
2125 }
2126 const std::string& path = subtree[0].first;
2127 const std::string& service = subtree[0].second.begin()->first;
2128 if (service.empty())
2129 {
2130 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2131 messages::internalError(aResp->res);
2132 return;
2133 }
2134
2135 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2136 << path;
2137
2138 // Set the Power Mode property
2139 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002140 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002141 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002142 {
Chris Cain3a2d04242021-05-28 16:57:10 -05002143 messages::internalError(aResp->res);
2144 return;
2145 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002146 },
2147 service, path, "org.freedesktop.DBus.Properties", "Set",
2148 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2149 dbus::utility::DbusVariantType(powerMode));
George Liue99073f2022-12-09 11:06:16 +08002150 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002151}
2152
2153/**
Yong Li51709ff2019-09-30 14:13:04 +08002154 * @brief Translates watchdog timeout action DBUS property value to redfish.
2155 *
2156 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2157 *
2158 * @return Returns as a string, the timeout action in Redfish terms. If
2159 * translation cannot be done, returns an empty string.
2160 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002161inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002162{
2163 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2164 {
2165 return "None";
2166 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002167 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002168 {
2169 return "ResetSystem";
2170 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002171 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002172 {
2173 return "PowerDown";
2174 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002175 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002176 {
2177 return "PowerCycle";
2178 }
2179
2180 return "";
2181}
2182
2183/**
Yong Lic45f0082019-10-10 14:19:01 +08002184 *@brief Translates timeout action from Redfish to DBUS property value.
2185 *
2186 *@param[in] rfAction The timeout action in Redfish.
2187 *
2188 *@return Returns as a string, the time_out action as expected by DBUS.
2189 *If translation cannot be done, returns an empty string.
2190 */
2191
Ed Tanous23a21a12020-07-25 04:45:05 +00002192inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002193{
2194 if (rfAction == "None")
2195 {
2196 return "xyz.openbmc_project.State.Watchdog.Action.None";
2197 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002198 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002199 {
2200 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2201 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002202 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002203 {
2204 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2205 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002206 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002207 {
2208 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2209 }
2210
2211 return "";
2212}
2213
2214/**
Yong Li51709ff2019-09-30 14:13:04 +08002215 * @brief Retrieves host watchdog timer properties over DBUS
2216 *
2217 * @param[in] aResp Shared pointer for completing asynchronous calls.
2218 *
2219 * @return None.
2220 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002221inline void
2222 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08002223{
2224 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002225 sdbusplus::asio::getAllProperties(
2226 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2227 "/xyz/openbmc_project/watchdog/host0",
2228 "xyz.openbmc_project.State.Watchdog",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002229 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002230 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002231 if (ec)
2232 {
2233 // watchdog service is stopped
2234 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2235 return;
2236 }
2237
2238 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2239
2240 nlohmann::json& hostWatchdogTimer =
2241 aResp->res.jsonValue["HostWatchdogTimer"];
2242
2243 // watchdog service is running/enabled
2244 hostWatchdogTimer["Status"]["State"] = "Enabled";
2245
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002246 const bool* enabled = nullptr;
2247 const std::string* expireAction = nullptr;
2248
2249 const bool success = sdbusplus::unpackPropertiesNoThrow(
2250 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2251 "ExpireAction", expireAction);
2252
2253 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002254 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002255 messages::internalError(aResp->res);
2256 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002257 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002258
2259 if (enabled != nullptr)
2260 {
2261 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2262 }
2263
2264 if (expireAction != nullptr)
2265 {
2266 std::string action = dbusToRfWatchdogAction(*expireAction);
2267 if (action.empty())
2268 {
2269 messages::internalError(aResp->res);
2270 return;
2271 }
2272 hostWatchdogTimer["TimeoutAction"] = action;
2273 }
2274 });
Yong Li51709ff2019-09-30 14:13:04 +08002275}
2276
2277/**
Yong Lic45f0082019-10-10 14:19:01 +08002278 * @brief Sets Host WatchDog Timer properties.
2279 *
2280 * @param[in] aResp Shared pointer for generating response message.
2281 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2282 * RF request.
2283 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2284 *
2285 * @return None.
2286 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002287inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08002288 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002289 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002290{
2291 BMCWEB_LOG_DEBUG << "Set host watchdog";
2292
2293 if (wdtTimeOutAction)
2294 {
2295 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2296 // check if TimeOut Action is Valid
2297 if (wdtTimeOutActStr.empty())
2298 {
2299 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2300 << *wdtTimeOutAction;
2301 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2302 "TimeoutAction");
2303 return;
2304 }
2305
2306 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002307 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002308 if (ec)
2309 {
2310 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2311 messages::internalError(aResp->res);
2312 return;
2313 }
Yong Lic45f0082019-10-10 14:19:01 +08002314 },
2315 "xyz.openbmc_project.Watchdog",
2316 "/xyz/openbmc_project/watchdog/host0",
2317 "org.freedesktop.DBus.Properties", "Set",
2318 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002319 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002320 }
2321
2322 if (wdtEnable)
2323 {
2324 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002325 [aResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002326 if (ec)
2327 {
2328 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2329 messages::internalError(aResp->res);
2330 return;
2331 }
Yong Lic45f0082019-10-10 14:19:01 +08002332 },
2333 "xyz.openbmc_project.Watchdog",
2334 "/xyz/openbmc_project/watchdog/host0",
2335 "org.freedesktop.DBus.Properties", "Set",
2336 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002337 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002338 }
2339}
2340
Chris Cain37bbf982021-09-20 10:53:09 -05002341/**
2342 * @brief Parse the Idle Power Saver properties into json
2343 *
2344 * @param[in] aResp Shared pointer for completing asynchronous calls.
2345 * @param[in] properties IPS property data from DBus.
2346 *
2347 * @return true if successful
2348 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002349inline bool
2350 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2351 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002352{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002353 const bool* enabled = nullptr;
2354 const uint8_t* enterUtilizationPercent = nullptr;
2355 const uint64_t* enterDwellTime = nullptr;
2356 const uint8_t* exitUtilizationPercent = nullptr;
2357 const uint64_t* exitDwellTime = nullptr;
2358
2359 const bool success = sdbusplus::unpackPropertiesNoThrow(
2360 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2361 "EnterUtilizationPercent", enterUtilizationPercent,
2362 "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime",
2363 exitDwellTime);
2364
2365 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002366 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002367 return false;
2368 }
2369
2370 if (enabled != nullptr)
2371 {
2372 aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
2373 }
2374
2375 if (enterUtilizationPercent != nullptr)
2376 {
2377 aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2378 *enterUtilizationPercent;
2379 }
2380
2381 if (enterDwellTime != nullptr)
2382 {
2383 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2384 aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
2385 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2386 .count();
2387 }
2388
2389 if (exitUtilizationPercent != nullptr)
2390 {
2391 aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2392 *exitUtilizationPercent;
2393 }
2394
2395 if (exitDwellTime != nullptr)
2396 {
2397 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2398 aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
2399 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2400 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002401 }
2402
2403 return true;
2404}
2405
2406/**
2407 * @brief Retrieves host watchdog timer properties over DBUS
2408 *
2409 * @param[in] aResp Shared pointer for completing asynchronous calls.
2410 *
2411 * @return None.
2412 */
2413inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
2414{
2415 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2416
2417 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002418 constexpr std::array<std::string_view, 1> interfaces = {
2419 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2420 dbus::utility::getSubTree(
2421 "/", 0, interfaces,
2422 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002423 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002424 if (ec)
2425 {
2426 BMCWEB_LOG_DEBUG
2427 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2428 << ec;
2429 messages::internalError(aResp->res);
2430 return;
2431 }
2432 if (subtree.empty())
2433 {
2434 // This is an optional interface so just return
2435 // if there is no instance found
2436 BMCWEB_LOG_DEBUG << "No instances found";
2437 return;
2438 }
2439 if (subtree.size() > 1)
2440 {
2441 // More then one PowerIdlePowerSaver object is not supported and
2442 // is an error
2443 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2444 "Power.IdlePowerSaver objects: "
2445 << subtree.size();
2446 messages::internalError(aResp->res);
2447 return;
2448 }
2449 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2450 {
2451 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2452 messages::internalError(aResp->res);
2453 return;
2454 }
2455 const std::string& path = subtree[0].first;
2456 const std::string& service = subtree[0].second.begin()->first;
2457 if (service.empty())
2458 {
2459 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2460 messages::internalError(aResp->res);
2461 return;
2462 }
2463
2464 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002465 sdbusplus::asio::getAllProperties(
2466 *crow::connections::systemBus, service, path,
2467 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002468 [aResp](const boost::system::error_code& ec2,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002469 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002470 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002471 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002472 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002473 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Chris Cain37bbf982021-09-20 10:53:09 -05002474 messages::internalError(aResp->res);
2475 return;
2476 }
2477
Ed Tanous002d39b2022-05-31 08:59:27 -07002478 if (!parseIpsProperties(aResp, properties))
2479 {
2480 messages::internalError(aResp->res);
2481 return;
2482 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002483 });
George Liue99073f2022-12-09 11:06:16 +08002484 });
Chris Cain37bbf982021-09-20 10:53:09 -05002485
2486 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2487}
2488
2489/**
2490 * @brief Sets Idle Power Saver properties.
2491 *
2492 * @param[in] aResp Shared pointer for generating response message.
2493 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2494 * RF request.
2495 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2496 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2497 * before entering idle state.
2498 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2499 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2500 * before exiting idle state
2501 *
2502 * @return None.
2503 */
2504inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2505 const std::optional<bool> ipsEnable,
2506 const std::optional<uint8_t> ipsEnterUtil,
2507 const std::optional<uint64_t> ipsEnterTime,
2508 const std::optional<uint8_t> ipsExitUtil,
2509 const std::optional<uint64_t> ipsExitTime)
2510{
2511 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2512
2513 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002514 constexpr std::array<std::string_view, 1> interfaces = {
2515 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2516 dbus::utility::getSubTree(
2517 "/", 0, interfaces,
Chris Cain37bbf982021-09-20 10:53:09 -05002518 [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002519 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002520 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002521 if (ec)
2522 {
2523 BMCWEB_LOG_DEBUG
2524 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2525 << ec;
2526 messages::internalError(aResp->res);
2527 return;
2528 }
2529 if (subtree.empty())
2530 {
2531 // This is an optional D-Bus object, but user attempted to patch
2532 messages::resourceNotFound(aResp->res, "ComputerSystem",
2533 "IdlePowerSaver");
2534 return;
2535 }
2536 if (subtree.size() > 1)
2537 {
2538 // More then one PowerIdlePowerSaver object is not supported and
2539 // is an error
2540 BMCWEB_LOG_DEBUG
2541 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2542 << subtree.size();
2543 messages::internalError(aResp->res);
2544 return;
2545 }
2546 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2547 {
2548 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2549 messages::internalError(aResp->res);
2550 return;
2551 }
2552 const std::string& path = subtree[0].first;
2553 const std::string& service = subtree[0].second.begin()->first;
2554 if (service.empty())
2555 {
2556 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2557 messages::internalError(aResp->res);
2558 return;
2559 }
Chris Cain37bbf982021-09-20 10:53:09 -05002560
Ed Tanous002d39b2022-05-31 08:59:27 -07002561 // Valid Power IdlePowerSaver object found, now set any values that
2562 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002563
Ed Tanous002d39b2022-05-31 08:59:27 -07002564 if (ipsEnable)
2565 {
2566 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002567 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002568 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002569 {
Ed Tanous8a592812022-06-04 09:06:59 -07002570 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002571 messages::internalError(aResp->res);
2572 return;
2573 }
2574 },
2575 service, path, "org.freedesktop.DBus.Properties", "Set",
2576 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2577 dbus::utility::DbusVariantType(*ipsEnable));
2578 }
2579 if (ipsEnterUtil)
2580 {
2581 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002582 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002583 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002584 {
Ed Tanous8a592812022-06-04 09:06:59 -07002585 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002586 messages::internalError(aResp->res);
2587 return;
2588 }
2589 },
2590 service, path, "org.freedesktop.DBus.Properties", "Set",
2591 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2592 "EnterUtilizationPercent",
2593 dbus::utility::DbusVariantType(*ipsEnterUtil));
2594 }
2595 if (ipsEnterTime)
2596 {
2597 // Convert from seconds into milliseconds for DBus
2598 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2599 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002600 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002601 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002602 {
Ed Tanous8a592812022-06-04 09:06:59 -07002603 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002604 messages::internalError(aResp->res);
2605 return;
2606 }
2607 },
2608 service, path, "org.freedesktop.DBus.Properties", "Set",
2609 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2610 "EnterDwellTime",
2611 dbus::utility::DbusVariantType(timeMilliseconds));
2612 }
2613 if (ipsExitUtil)
2614 {
2615 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002616 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002617 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002618 {
Ed Tanous8a592812022-06-04 09:06:59 -07002619 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002620 messages::internalError(aResp->res);
2621 return;
2622 }
2623 },
2624 service, path, "org.freedesktop.DBus.Properties", "Set",
2625 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2626 "ExitUtilizationPercent",
2627 dbus::utility::DbusVariantType(*ipsExitUtil));
2628 }
2629 if (ipsExitTime)
2630 {
2631 // Convert from seconds into milliseconds for DBus
2632 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2633 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002634 [aResp](const boost::system::error_code& ec2) {
Ed Tanous8a592812022-06-04 09:06:59 -07002635 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002636 {
Ed Tanous8a592812022-06-04 09:06:59 -07002637 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002638 messages::internalError(aResp->res);
2639 return;
2640 }
2641 },
2642 service, path, "org.freedesktop.DBus.Properties", "Set",
2643 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2644 "ExitDwellTime",
2645 dbus::utility::DbusVariantType(timeMilliseconds));
2646 }
George Liue99073f2022-12-09 11:06:16 +08002647 });
Chris Cain37bbf982021-09-20 10:53:09 -05002648
2649 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2650}
2651
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002652inline void handleComputerSystemHead(
2653 crow::App& app, const crow::Request& req,
2654 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2655{
2656 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2657 {
2658 return;
2659 }
2660 asyncResp->res.addHeader(
2661 boost::beast::http::field::link,
2662 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2663}
2664
Yong Lic45f0082019-10-10 14:19:01 +08002665/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002666 * SystemsCollection derived class for delivering ComputerSystems Collection
2667 * Schema
2668 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002669inline void requestRoutesSystemsCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002670{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002671 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002672 .privileges(redfish::privileges::headComputerSystemCollection)
2673 .methods(boost::beast::http::verb::head)(
2674 std::bind_front(handleComputerSystemHead, std::ref(app)));
2675
2676 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanoused398212021-06-09 17:05:54 -07002677 .privileges(redfish::privileges::getComputerSystemCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002678 .methods(boost::beast::http::verb::get)(
Ed Tanousf4c99e72021-10-04 17:02:43 -07002679 [&app](const crow::Request& req,
2680 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002681 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002682 {
2683 return;
2684 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002685
2686 asyncResp->res.addHeader(
2687 boost::beast::http::field::link,
2688 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002689 asyncResp->res.jsonValue["@odata.type"] =
2690 "#ComputerSystemCollection.ComputerSystemCollection";
2691 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2692 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002693
Ed Tanous002d39b2022-05-31 08:59:27 -07002694 sdbusplus::asio::getProperty<std::string>(
2695 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2696 "/xyz/openbmc_project/network/hypervisor",
2697 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002698 [asyncResp](const boost::system::error_code& ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002699 const std::string& /*hostName*/) {
2700 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2701 ifaceArray = nlohmann::json::array();
2702 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Ed Tanous14766872022-03-15 10:44:42 -07002703
Ed Tanous002d39b2022-05-31 08:59:27 -07002704 nlohmann::json::object_t system;
2705 system["@odata.id"] = "/redfish/v1/Systems/system";
2706 ifaceArray.push_back(std::move(system));
2707 count = ifaceArray.size();
Ed Tanous8a592812022-06-04 09:06:59 -07002708 if (!ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002709 {
2710 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2711 nlohmann::json::object_t hypervisor;
2712 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2713 ifaceArray.push_back(std::move(hypervisor));
2714 count = ifaceArray.size();
2715 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002716 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002717 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002718}
Sunitha Harish462023a2020-02-19 08:34:59 -06002719
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002720/**
2721 * Function transceives data with dbus directly.
2722 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002723inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002724{
2725 constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2726 constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2727 constexpr char const* interfaceName =
2728 "xyz.openbmc_project.Control.Host.NMI";
2729 constexpr char const* method = "NMI";
2730
2731 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002732 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002733 if (ec)
2734 {
2735 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2736 messages::internalError(asyncResp->res);
2737 return;
2738 }
2739 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002740 },
2741 serviceName, objectPath, interfaceName, method);
2742}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002743
2744/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002745 * SystemActionsReset class supports handle POST method for Reset action.
2746 * The class retrieves and sends data directly to D-Bus.
2747 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002748inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002749{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002750 /**
2751 * Function handles POST method request.
2752 * Analyzes POST body message before sends Reset request data to D-Bus.
2753 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002754 BMCWEB_ROUTE(app,
2755 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002756 .privileges(redfish::privileges::postComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002757 .methods(boost::beast::http::verb::post)(
2758 [&app](const crow::Request& req,
2759 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002760 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002761 {
2762 return;
2763 }
2764 std::string resetType;
2765 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
2766 resetType))
2767 {
2768 return;
2769 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002770
Ed Tanous002d39b2022-05-31 08:59:27 -07002771 // Get the command and host vs. chassis
2772 std::string command;
2773 bool hostCommand = true;
2774 if ((resetType == "On") || (resetType == "ForceOn"))
2775 {
2776 command = "xyz.openbmc_project.State.Host.Transition.On";
2777 hostCommand = true;
2778 }
2779 else if (resetType == "ForceOff")
2780 {
2781 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2782 hostCommand = false;
2783 }
2784 else if (resetType == "ForceRestart")
2785 {
2786 command =
2787 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2788 hostCommand = true;
2789 }
2790 else if (resetType == "GracefulShutdown")
2791 {
2792 command = "xyz.openbmc_project.State.Host.Transition.Off";
2793 hostCommand = true;
2794 }
2795 else if (resetType == "GracefulRestart")
2796 {
2797 command =
2798 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2799 hostCommand = true;
2800 }
2801 else if (resetType == "PowerCycle")
2802 {
2803 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2804 hostCommand = true;
2805 }
2806 else if (resetType == "Nmi")
2807 {
2808 doNMI(asyncResp);
2809 return;
2810 }
2811 else
2812 {
2813 messages::actionParameterUnknown(asyncResp->res, "Reset",
2814 resetType);
2815 return;
2816 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002817
Ed Tanous002d39b2022-05-31 08:59:27 -07002818 if (hostCommand)
2819 {
2820 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002821 [asyncResp, resetType](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002822 if (ec)
2823 {
2824 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2825 if (ec.value() == boost::asio::error::invalid_argument)
2826 {
2827 messages::actionParameterNotSupported(
2828 asyncResp->res, resetType, "Reset");
2829 }
2830 else
2831 {
2832 messages::internalError(asyncResp->res);
2833 }
2834 return;
2835 }
2836 messages::success(asyncResp->res);
2837 },
2838 "xyz.openbmc_project.State.Host",
2839 "/xyz/openbmc_project/state/host0",
2840 "org.freedesktop.DBus.Properties", "Set",
2841 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2842 dbus::utility::DbusVariantType{command});
2843 }
2844 else
2845 {
2846 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -08002847 [asyncResp, resetType](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002848 if (ec)
2849 {
2850 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2851 if (ec.value() == boost::asio::error::invalid_argument)
2852 {
2853 messages::actionParameterNotSupported(
2854 asyncResp->res, resetType, "Reset");
2855 }
2856 else
2857 {
2858 messages::internalError(asyncResp->res);
2859 }
2860 return;
2861 }
2862 messages::success(asyncResp->res);
2863 },
2864 "xyz.openbmc_project.State.Chassis",
2865 "/xyz/openbmc_project/state/chassis0",
2866 "org.freedesktop.DBus.Properties", "Set",
2867 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2868 dbus::utility::DbusVariantType{command});
2869 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002870 });
2871}
Ed Tanouscc340dd2018-08-29 13:43:38 -07002872
Ed Tanous38c8a6f2022-09-01 16:37:27 -07002873inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002874 App& app, const crow::Request& req,
2875 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2876{
2877 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2878 {
2879 return;
2880 }
2881
2882 asyncResp->res.addHeader(
2883 boost::beast::http::field::link,
2884 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2885}
2886
Abhishek Patel5c3e9272021-06-24 10:11:33 -05002887inline void afterPortRequest(
2888 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2889 const boost::system::error_code& ec,
2890 const std::vector<std::tuple<std::string, std::string, bool>>& socketData)
2891{
2892 if (ec)
2893 {
2894 messages::internalError(asyncResp->res);
2895 return;
2896 }
2897 for (const auto& data : socketData)
2898 {
2899 const std::string& socketPath = get<0>(data);
2900 const std::string& protocolName = get<1>(data);
2901 bool isProtocolEnabled = get<2>(data);
2902 nlohmann::json& dataJson = asyncResp->res.jsonValue["SerialConsole"];
2903 dataJson[protocolName]["ServiceEnabled"] = isProtocolEnabled;
2904 // need to retrieve port number for
2905 // obmc-console-ssh service
2906 if (protocolName == "SSH")
2907 {
2908 getPortNumber(socketPath, [asyncResp, protocolName](
2909 const boost::system::error_code ec1,
2910 int portNumber) {
2911 if (ec1)
2912 {
2913 messages::internalError(asyncResp->res);
2914 return;
2915 }
2916 nlohmann::json& dataJson1 =
2917 asyncResp->res.jsonValue["SerialConsole"];
2918 dataJson1[protocolName]["Port"] = portNumber;
2919 });
2920 }
2921 }
2922}
Ed Tanouscc340dd2018-08-29 13:43:38 -07002923/**
Ed Tanous66173382018-08-15 18:20:59 -07002924 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002925 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002926inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002927{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002928
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002929 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2930 .privileges(redfish::privileges::headComputerSystem)
2931 .methods(boost::beast::http::verb::head)(
2932 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002933 /**
2934 * Functions triggers appropriate requests on DBus
2935 */
Ed Tanous22d268c2022-05-19 09:39:07 -07002936 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002937 .privileges(redfish::privileges::getComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002938 .methods(boost::beast::http::verb::get)(
2939 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002940 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2941 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002942 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002943 {
2944 return;
2945 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06002946
2947 if (systemName == "hypervisor")
2948 {
2949 handleHypervisorSystemGet(asyncResp);
2950 return;
2951 }
2952
Ed Tanous22d268c2022-05-19 09:39:07 -07002953 if (systemName != "system")
2954 {
2955 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2956 systemName);
2957 return;
2958 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002959 asyncResp->res.addHeader(
2960 boost::beast::http::field::link,
2961 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002962 asyncResp->res.jsonValue["@odata.type"] =
2963 "#ComputerSystem.v1_16_0.ComputerSystem";
2964 asyncResp->res.jsonValue["Name"] = "system";
2965 asyncResp->res.jsonValue["Id"] = "system";
2966 asyncResp->res.jsonValue["SystemType"] = "Physical";
2967 asyncResp->res.jsonValue["Description"] = "Computer System";
2968 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
2969 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
2970 "Disabled";
2971 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
2972 uint64_t(0);
2973 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
2974 "Disabled";
2975 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07002976
Ed Tanous002d39b2022-05-31 08:59:27 -07002977 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
2978 "/redfish/v1/Systems/system/Processors";
2979 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
2980 "/redfish/v1/Systems/system/Memory";
2981 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
2982 "/redfish/v1/Systems/system/Storage";
Sunny Srivastava31791052021-03-12 10:39:16 -06002983 asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] =
2984 "/redfish/v1/Systems/system/FabricAdapters";
Ed Tanous029573d2019-02-01 10:57:49 -08002985
Ed Tanous002d39b2022-05-31 08:59:27 -07002986 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
2987 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
2988 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
2989 ["@Redfish.ActionInfo"] =
2990 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002991
Ed Tanous002d39b2022-05-31 08:59:27 -07002992 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
2993 "/redfish/v1/Systems/system/LogServices";
2994 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
2995 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08002996
Ed Tanous002d39b2022-05-31 08:59:27 -07002997 nlohmann::json::array_t managedBy;
2998 nlohmann::json& manager = managedBy.emplace_back();
2999 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
3000 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
3001 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
3002 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003003
Ed Tanous002d39b2022-05-31 08:59:27 -07003004 // Fill in SerialConsole info
3005 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
3006 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
3007 true;
Ed Tanous14766872022-03-15 10:44:42 -07003008
Ed Tanous002d39b2022-05-31 08:59:27 -07003009 // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
3010 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
3011 true;
3012 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
3013 asyncResp->res
3014 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
3015 "Press ~. to exit console";
Abhishek Patel5c3e9272021-06-24 10:11:33 -05003016 getPortStatusAndPath(std::span{protocolToDBusForSystems},
3017 std::bind_front(afterPortRequest, asyncResp));
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003018
3019#ifdef BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07003020 // Fill in GraphicalConsole info
3021 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
3022 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
3023 4;
Ed Tanous613dabe2022-07-09 11:17:36 -07003024 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
3025 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07003026
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06003027#endif // BMCWEB_ENABLE_KVM
George Liu7a1dbc42022-12-07 16:03:22 +08003028 constexpr std::array<std::string_view, 4> inventoryForSystems{
Ed Tanous002d39b2022-05-31 08:59:27 -07003029 "xyz.openbmc_project.Inventory.Item.Dimm",
3030 "xyz.openbmc_project.Inventory.Item.Cpu",
3031 "xyz.openbmc_project.Inventory.Item.Drive",
3032 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07003033
Ed Tanous002d39b2022-05-31 08:59:27 -07003034 auto health = std::make_shared<HealthPopulate>(asyncResp);
George Liu7a1dbc42022-12-07 16:03:22 +08003035 dbus::utility::getSubTreePaths(
3036 "/", 0, inventoryForSystems,
3037 [health](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -07003038 const std::vector<std::string>& resp) {
3039 if (ec)
3040 {
3041 // no inventory
3042 return;
3043 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003044
Ed Tanous002d39b2022-05-31 08:59:27 -07003045 health->inventory = resp;
George Liu7a1dbc42022-12-07 16:03:22 +08003046 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003047
Ed Tanous002d39b2022-05-31 08:59:27 -07003048 health->populate();
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003049
Ed Tanous002d39b2022-05-31 08:59:27 -07003050 getMainChassisId(asyncResp,
3051 [](const std::string& chassisId,
3052 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3053 nlohmann::json::array_t chassisArray;
3054 nlohmann::json& chassis = chassisArray.emplace_back();
Willy Tueddfc432022-09-26 16:46:38 +00003055 chassis["@odata.id"] = crow::utility::urlFromPieces(
3056 "redfish", "v1", "Chassis", chassisId);
Ed Tanous002d39b2022-05-31 08:59:27 -07003057 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3058 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003059
Ed Tanous002d39b2022-05-31 08:59:27 -07003060 getLocationIndicatorActive(asyncResp);
3061 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3062 getIndicatorLedState(asyncResp);
3063 getComputerSystem(asyncResp, health);
3064 getHostState(asyncResp);
3065 getBootProperties(asyncResp);
3066 getBootProgress(asyncResp);
Hieu Huynhb6d5d452022-10-07 09:41:46 +00003067 getBootProgressLastStateTime(asyncResp);
Ed Tanous002d39b2022-05-31 08:59:27 -07003068 getPCIeDeviceList(asyncResp, "PCIeDevices");
3069 getHostWatchdogTimer(asyncResp);
3070 getPowerRestorePolicy(asyncResp);
3071 getAutomaticRetry(asyncResp);
3072 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003073#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanous002d39b2022-05-31 08:59:27 -07003074 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003075#endif
Ed Tanous002d39b2022-05-31 08:59:27 -07003076 getTrustedModuleRequiredToBoot(asyncResp);
3077 getPowerMode(asyncResp);
3078 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003079 });
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003080
Ed Tanous22d268c2022-05-19 09:39:07 -07003081 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003082 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003083 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003084 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003085 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3086 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003087 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003088 {
3089 return;
3090 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003091 if (systemName != "system")
3092 {
3093 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3094 systemName);
3095 return;
3096 }
3097
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003098 asyncResp->res.addHeader(
3099 boost::beast::http::field::link,
3100 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3101
Ed Tanous002d39b2022-05-31 08:59:27 -07003102 std::optional<bool> locationIndicatorActive;
3103 std::optional<std::string> indicatorLed;
3104 std::optional<std::string> assetTag;
3105 std::optional<std::string> powerRestorePolicy;
3106 std::optional<std::string> powerMode;
3107 std::optional<bool> wdtEnable;
3108 std::optional<std::string> wdtTimeOutAction;
3109 std::optional<std::string> bootSource;
3110 std::optional<std::string> bootType;
3111 std::optional<std::string> bootEnable;
3112 std::optional<std::string> bootAutomaticRetry;
3113 std::optional<bool> bootTrustedModuleRequired;
3114 std::optional<bool> ipsEnable;
3115 std::optional<uint8_t> ipsEnterUtil;
3116 std::optional<uint64_t> ipsEnterTime;
3117 std::optional<uint8_t> ipsExitUtil;
3118 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003119
Ed Tanous002d39b2022-05-31 08:59:27 -07003120 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003121 if (!json_util::readJsonPatch(
3122 req, asyncResp->res,
3123 "IndicatorLED", indicatorLed,
3124 "LocationIndicatorActive", locationIndicatorActive,
3125 "AssetTag", assetTag,
3126 "PowerRestorePolicy", powerRestorePolicy,
3127 "PowerMode", powerMode,
3128 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3129 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3130 "Boot/BootSourceOverrideTarget", bootSource,
3131 "Boot/BootSourceOverrideMode", bootType,
3132 "Boot/BootSourceOverrideEnabled", bootEnable,
3133 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3134 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3135 "IdlePowerSaver/Enabled", ipsEnable,
3136 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3137 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3138 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3139 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3140 {
3141 return;
3142 }
Ed Tanous002d39b2022-05-31 08:59:27 -07003143 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003144
Ed Tanous002d39b2022-05-31 08:59:27 -07003145 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003146
Ed Tanous002d39b2022-05-31 08:59:27 -07003147 if (assetTag)
3148 {
3149 setAssetTag(asyncResp, *assetTag);
3150 }
James Feistb49ac872019-05-21 15:12:01 -07003151
Ed Tanous002d39b2022-05-31 08:59:27 -07003152 if (wdtEnable || wdtTimeOutAction)
3153 {
3154 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3155 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003156
Ed Tanous002d39b2022-05-31 08:59:27 -07003157 if (bootSource || bootType || bootEnable)
3158 {
3159 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3160 }
3161 if (bootAutomaticRetry)
3162 {
3163 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3164 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003165
Ed Tanous002d39b2022-05-31 08:59:27 -07003166 if (bootTrustedModuleRequired)
3167 {
3168 setTrustedModuleRequiredToBoot(asyncResp,
3169 *bootTrustedModuleRequired);
3170 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003171
Ed Tanous002d39b2022-05-31 08:59:27 -07003172 if (locationIndicatorActive)
3173 {
3174 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3175 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003176
Ed Tanous002d39b2022-05-31 08:59:27 -07003177 // TODO (Gunnar): Remove IndicatorLED after enough time has
3178 // passed
3179 if (indicatorLed)
3180 {
3181 setIndicatorLedState(asyncResp, *indicatorLed);
3182 asyncResp->res.addHeader(boost::beast::http::field::warning,
3183 "299 - \"IndicatorLED is deprecated. Use "
3184 "LocationIndicatorActive instead.\"");
3185 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003186
Ed Tanous002d39b2022-05-31 08:59:27 -07003187 if (powerRestorePolicy)
3188 {
3189 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3190 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003191
Ed Tanous002d39b2022-05-31 08:59:27 -07003192 if (powerMode)
3193 {
3194 setPowerMode(asyncResp, *powerMode);
3195 }
Chris Cain37bbf982021-09-20 10:53:09 -05003196
Ed Tanous002d39b2022-05-31 08:59:27 -07003197 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3198 ipsExitTime)
3199 {
3200 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3201 ipsExitUtil, ipsExitTime);
3202 }
3203 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003204}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303205
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003206inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003207 crow::App& app, const crow::Request& req,
3208 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3209{
3210 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3211 {
3212 return;
3213 }
3214 asyncResp->res.addHeader(
3215 boost::beast::http::field::link,
3216 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3217}
3218
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303219/**
3220 * SystemResetActionInfo derived class for delivering Computer Systems
3221 * ResetType AllowableValues using ResetInfo schema.
3222 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003223inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303224{
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003225 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3226 .privileges(redfish::privileges::headActionInfo)
3227 .methods(boost::beast::http::verb::head)(std::bind_front(
3228 handleSystemCollectionResetActionHead, std::ref(app)));
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303229 /**
3230 * Functions triggers appropriate requests on DBus
3231 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003232 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003233 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003234 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003235 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003236 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3237 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003238 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003239 {
3240 return;
3241 }
Asmitha Karunanithi746b56f2023-02-27 23:29:49 -06003242
3243 if (systemName == "hypervisor")
3244 {
3245 handleHypervisorResetActionGet(asyncResp);
3246 return;
3247 }
3248
Ed Tanous22d268c2022-05-19 09:39:07 -07003249 if (systemName != "system")
3250 {
3251 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3252 systemName);
3253 return;
3254 }
3255
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003256 asyncResp->res.addHeader(
3257 boost::beast::http::field::link,
3258 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
Ed Tanous14766872022-03-15 10:44:42 -07003259
Ed Tanous002d39b2022-05-31 08:59:27 -07003260 asyncResp->res.jsonValue["@odata.id"] =
3261 "/redfish/v1/Systems/system/ResetActionInfo";
3262 asyncResp->res.jsonValue["@odata.type"] =
3263 "#ActionInfo.v1_1_2.ActionInfo";
3264 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3265 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
Nan Zhou3215e702022-06-01 16:55:13 +00003266
3267 nlohmann::json::array_t parameters;
3268 nlohmann::json::object_t parameter;
3269
3270 parameter["Name"] = "ResetType";
3271 parameter["Required"] = true;
3272 parameter["DataType"] = "String";
3273 nlohmann::json::array_t allowableValues;
3274 allowableValues.emplace_back("On");
3275 allowableValues.emplace_back("ForceOff");
3276 allowableValues.emplace_back("ForceOn");
3277 allowableValues.emplace_back("ForceRestart");
3278 allowableValues.emplace_back("GracefulRestart");
3279 allowableValues.emplace_back("GracefulShutdown");
3280 allowableValues.emplace_back("PowerCycle");
3281 allowableValues.emplace_back("Nmi");
3282 parameter["AllowableValues"] = std::move(allowableValues);
3283 parameters.emplace_back(std::move(parameter));
3284
3285 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
Ed Tanous002d39b2022-05-31 08:59:27 -07003286 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003287}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003288} // namespace redfish