blob: caf6a292ca3b5f963553a730cfb358fc83706bc1 [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
Jonathan Doman1e1e5982021-06-11 09:36:17 -070018#include "dbus_singleton.hpp"
James Feistb49ac872019-05-21 15:12:01 -070019#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080020#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080021#include "pcie.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070022#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080023#include "redfish_util.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070024#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080025
John Edward Broadbent7e860f12021-04-08 15:57:16 -070026#include <app.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070027#include <boost/container/flat_map.hpp>
Ed Tanous168e20c2021-12-13 14:39:53 -080028#include <dbus_utility.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070029#include <registries/privilege_registry.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070030#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020031#include <sdbusplus/unpack_properties.hpp>
32#include <utils/dbus_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020033#include <utils/json_utils.hpp>
Willy Tueee00132022-06-14 14:53:17 -070034#include <utils/sw_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050035
Ed Tanousabf2add2019-01-22 16:40:12 -080036#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020037
Ed Tanous1abe55e2018-09-05 08:30:59 -070038namespace redfish
39{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020040
Alpana Kumari9d3ae102019-04-12 06:49:32 -050041/**
42 * @brief Updates the Functional State of DIMMs
43 *
44 * @param[in] aResp Shared pointer for completing asynchronous calls
45 * @param[in] dimmState Dimm's Functional state, true/false
46 *
47 * @return None.
48 */
zhanghch058d1b46d2021-04-01 11:18:24 +080049inline void
50 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070051 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050052{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070053 BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050054
Gunnar Mills4e0453b2020-07-08 14:00:30 -050055 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056 // Update STATE only if previous State was DISABLED and current Dimm is
57 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070058 const nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050059 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
60 if (prevMemSummary == "Disabled")
61 {
Ed Tanouse05aec52022-01-25 10:28:56 -080062 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050063 {
64 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
65 "Enabled";
66 }
67 }
68}
69
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050070/*
71 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
72 *
73 * @param[in] aResp Shared pointer for completing asynchronous calls
74 * @param[in] cpuPresenceState CPU present or not
75 *
76 * @return None.
77 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -070078inline void
79 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
80 bool isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050081{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070082 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050083
Ed Tanous55f79e62022-01-25 11:26:16 -080084 if (isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050086 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080087 aResp->res.jsonValue["ProcessorSummary"]["Count"];
Ed Tanous55f79e62022-01-25 11:26:16 -080088 auto* procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080090 if (procCountPtr != nullptr)
91 {
92 // shouldn't be possible to be nullptr
93 *procCountPtr += 1;
94 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050095 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050096}
97
98/*
99 * @brief Update "ProcessorSummary" "Status" "State" based on
100 * CPU Functional State
101 *
102 * @param[in] aResp Shared pointer for completing asynchronous calls
103 * @param[in] cpuFunctionalState is CPU functional true/false
104 *
105 * @return None.
106 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700107inline void
108 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
109 bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500110{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700111 BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500112
Ed Tanous02cad962022-06-30 16:50:15 -0700113 const nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
115
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500116 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500117 // Update STATE only if previous State was Non_Functional and current CPU is
118 // Functional.
119 if (prevProcState == "Disabled")
120 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800121 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500122 {
123 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
124 "Enabled";
125 }
126 }
127}
128
Ali Ahmed382d6472021-09-03 16:53:53 -0500129inline void getProcessorProperties(
130 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
131 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
132 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500133{
134
135 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
136
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200137 // TODO: Get Model
138
139 const uint16_t* coreCount = nullptr;
140
141 const bool success = sdbusplus::unpackPropertiesNoThrow(
142 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
143
144 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500145 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200146 messages::internalError(aResp->res);
147 return;
148 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500149
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200150 if (coreCount != nullptr)
151 {
152 nlohmann::json& coreCountJson =
153 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
154 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500155
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200156 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500157 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200158 coreCountJson = *coreCount;
159 }
160 else
161 {
162 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500163 }
164 }
165}
166
167/*
168 * @brief Get ProcessorSummary fields
169 *
170 * @param[in] aResp Shared pointer for completing asynchronous calls
171 * @param[in] service dbus service for Cpu Information
172 * @param[in] path dbus path for Cpu
173 *
174 * @return None.
175 */
176inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
177 const std::string& service,
178 const std::string& path)
179{
180
Ali Ahmed382d6472021-09-03 16:53:53 -0500181 auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
182 const bool cpuPresenceCheck) {
183 if (ec3)
184 {
185 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
186 return;
187 }
188 modifyCpuPresenceState(aResp, cpuPresenceCheck);
189 };
190
191 auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
192 const bool cpuFunctionalCheck) {
193 if (ec3)
194 {
195 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
196 return;
197 }
198 modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
199 };
200
201 // Get the Presence of CPU
202 sdbusplus::asio::getProperty<bool>(
203 *crow::connections::systemBus, service, path,
204 "xyz.openbmc_project.Inventory.Item", "Present",
205 std::move(getCpuPresenceState));
206
207 // Get the Functional State
208 sdbusplus::asio::getProperty<bool>(
209 *crow::connections::systemBus, service, path,
210 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
211 std::move(getCpuFunctionalState));
212
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200213 sdbusplus::asio::getAllProperties(
214 *crow::connections::systemBus, service, path,
215 "xyz.openbmc_project.Inventory.Item.Cpu",
Ali Ahmed03fbed92021-09-03 02:33:43 -0500216 [aResp, service,
217 path](const boost::system::error_code ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800218 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700219 if (ec2)
220 {
221 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
222 messages::internalError(aResp->res);
223 return;
224 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500225 getProcessorProperties(aResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200226 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500227}
228
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500229/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700230 * @brief Retrieves computer system properties over dbus
231 *
232 * @param[in] aResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500233 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700234 *
235 * @return None.
236 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700237inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800238 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700239 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700240{
Ed Tanous6c34de42018-08-29 13:37:36 -0700241 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500242
Ed Tanous6c34de42018-08-29 13:37:36 -0700243 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -0800244 [aResp,
245 systemHealth](const boost::system::error_code ec,
246 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700247 if (ec)
248 {
249 BMCWEB_LOG_DEBUG << "DBUS response error";
250 messages::internalError(aResp->res);
251 return;
252 }
253 // Iterate over all retrieved ObjectPaths.
254 for (const std::pair<
255 std::string,
256 std::vector<std::pair<std::string, std::vector<std::string>>>>&
257 object : subtree)
258 {
259 const std::string& path = object.first;
260 BMCWEB_LOG_DEBUG << "Got path: " << path;
261 const std::vector<std::pair<std::string, std::vector<std::string>>>&
262 connectionNames = object.second;
263 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700264 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700265 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700266 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700267
268 auto memoryHealth = std::make_shared<HealthPopulate>(
269 aResp, "/MemorySummary/Status"_json_pointer);
270
271 auto cpuHealth = std::make_shared<HealthPopulate>(
272 aResp, "/ProcessorSummary/Status"_json_pointer);
273
274 systemHealth->children.emplace_back(memoryHealth);
275 systemHealth->children.emplace_back(cpuHealth);
276
277 // This is not system, so check if it's cpu, dimm, UUID or
278 // BiosVer
279 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700280 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700281 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700282 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700283 if (interfaceName ==
284 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700285 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700286 BMCWEB_LOG_DEBUG
287 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500288
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200289 sdbusplus::asio::getAllProperties(
290 *crow::connections::systemBus, connection.first,
291 path, "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanous002d39b2022-05-31 08:59:27 -0700292 [aResp, service{connection.first},
293 path](const boost::system::error_code ec2,
294 const dbus::utility::DBusPropertiesMap&
295 properties) {
296 if (ec2)
297 {
298 BMCWEB_LOG_ERROR << "DBUS response error "
299 << ec2;
300 messages::internalError(aResp->res);
301 return;
302 }
303 BMCWEB_LOG_DEBUG << "Got " << properties.size()
304 << " Dimm properties.";
305
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200306 if (properties.empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700307 {
308 sdbusplus::asio::getProperty<bool>(
309 *crow::connections::systemBus, service,
310 path,
311 "xyz.openbmc_project.State."
312 "Decorator.OperationalStatus",
313 "Functional",
314 [aResp](const boost::system::error_code ec3,
315 bool dimmState) {
316 if (ec3)
317 {
318 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000319 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800320 return;
321 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700322 updateDimmProperties(aResp, dimmState);
323 });
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200324 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700325 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200326
327 const uint32_t* memorySizeInKB = nullptr;
328
329 const bool success =
330 sdbusplus::unpackPropertiesNoThrow(
331 dbus_utils::UnpackErrorPrinter(),
332 properties, "MemorySizeInKB",
333 memorySizeInKB);
334
335 if (!success)
336 {
337 messages::internalError(aResp->res);
338 return;
339 }
340
341 if (memorySizeInKB != nullptr)
342 {
343 nlohmann::json& totalMemory =
344 aResp->res
345 .jsonValue["MemorySummary"]
346 ["TotalSystemMemoryGiB"];
347 const uint64_t* preValue =
348 totalMemory.get_ptr<const uint64_t*>();
349 if (preValue == nullptr)
350 {
351 aResp->res
352 .jsonValue["MemorySummary"]
353 ["TotalSystemMemoryGiB"] =
354 *memorySizeInKB / (1024 * 1024);
355 }
356 else
357 {
358 aResp->res
359 .jsonValue["MemorySummary"]
360 ["TotalSystemMemoryGiB"] =
361 *memorySizeInKB / (1024 * 1024) +
362 *preValue;
363 }
364 aResp->res.jsonValue["MemorySummary"]["Status"]
365 ["State"] = "Enabled";
366 }
367 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700368
369 memoryHealth->inventory.emplace_back(path);
370 }
371 else if (interfaceName ==
372 "xyz.openbmc_project.Inventory.Item.Cpu")
373 {
374 BMCWEB_LOG_DEBUG
375 << "Found Cpu, now get its properties.";
376
377 getProcessorSummary(aResp, connection.first, path);
378
379 cpuHealth->inventory.emplace_back(path);
380 }
381 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
382 {
383 BMCWEB_LOG_DEBUG
384 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200385
386 sdbusplus::asio::getAllProperties(
387 *crow::connections::systemBus, connection.first,
388 path, "xyz.openbmc_project.Common.UUID",
Ed Tanous002d39b2022-05-31 08:59:27 -0700389 [aResp](const boost::system::error_code ec3,
390 const dbus::utility::DBusPropertiesMap&
391 properties) {
392 if (ec3)
393 {
394 BMCWEB_LOG_DEBUG << "DBUS response error "
395 << ec3;
396 messages::internalError(aResp->res);
397 return;
398 }
399 BMCWEB_LOG_DEBUG << "Got " << properties.size()
400 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700401
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200402 const std::string* uUID = nullptr;
403
404 const bool success =
405 sdbusplus::unpackPropertiesNoThrow(
406 dbus_utils::UnpackErrorPrinter(),
407 properties, "UUID", uUID);
408
409 if (!success)
410 {
411 messages::internalError(aResp->res);
412 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700413 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200414
415 if (uUID != nullptr)
416 {
417 std::string valueStr = *uUID;
418 if (valueStr.size() == 32)
419 {
420 valueStr.insert(8, 1, '-');
421 valueStr.insert(13, 1, '-');
422 valueStr.insert(18, 1, '-');
423 valueStr.insert(23, 1, '-');
424 }
425 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
426 aResp->res.jsonValue["UUID"] = valueStr;
427 }
428 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700429 }
430 else if (interfaceName ==
431 "xyz.openbmc_project.Inventory.Item.System")
432 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200433 sdbusplus::asio::getAllProperties(
434 *crow::connections::systemBus, connection.first,
435 path,
436 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanous002d39b2022-05-31 08:59:27 -0700437 [aResp](const boost::system::error_code ec2,
438 const dbus::utility::DBusPropertiesMap&
439 propertiesList) {
440 if (ec2)
441 {
442 // doesn't have to include this
443 // interface
444 return;
445 }
446 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
447 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200448
449 const std::string* partNumber = nullptr;
450 const std::string* serialNumber = nullptr;
451 const std::string* manufacturer = nullptr;
452 const std::string* model = nullptr;
453 const std::string* subModel = nullptr;
454
455 const bool success =
456 sdbusplus::unpackPropertiesNoThrow(
457 dbus_utils::UnpackErrorPrinter(),
458 propertiesList, "PartNumber", partNumber,
459 "SerialNumber", serialNumber,
460 "Manufacturer", manufacturer, "Model",
461 model, "SubModel", subModel);
462
463 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700464 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200465 messages::internalError(aResp->res);
466 return;
467 }
468
469 if (partNumber != nullptr)
470 {
471 aResp->res.jsonValue["PartNumber"] =
472 *partNumber;
473 }
474
475 if (serialNumber != nullptr)
476 {
477 aResp->res.jsonValue["SerialNumber"] =
478 *serialNumber;
479 }
480
481 if (manufacturer != nullptr)
482 {
483 aResp->res.jsonValue["Manufacturer"] =
484 *manufacturer;
485 }
486
487 if (model != nullptr)
488 {
489 aResp->res.jsonValue["Model"] = *model;
490 }
491
492 if (subModel != nullptr)
493 {
494 aResp->res.jsonValue["SubModel"] = *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700495 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500496
Ed Tanous002d39b2022-05-31 08:59:27 -0700497 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700498 sw_util::populateSoftwareInformation(
499 aResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700500 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200501 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700502
Ed Tanous002d39b2022-05-31 08:59:27 -0700503 sdbusplus::asio::getProperty<std::string>(
504 *crow::connections::systemBus, connection.first,
505 path,
506 "xyz.openbmc_project.Inventory.Decorator."
507 "AssetTag",
508 "AssetTag",
509 [aResp](const boost::system::error_code ec2,
510 const std::string& value) {
511 if (ec2)
512 {
513 // doesn't have to include this
514 // interface
515 return;
516 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700517
Ed Tanous002d39b2022-05-31 08:59:27 -0700518 aResp->res.jsonValue["AssetTag"] = value;
519 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700520 }
521 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200522 break;
Ed Tanous6c34de42018-08-29 13:37:36 -0700523 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700524 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700525 },
526 "xyz.openbmc_project.ObjectMapper",
527 "/xyz/openbmc_project/object_mapper",
528 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700529 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500530 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700531 "xyz.openbmc_project.Inventory.Decorator.Asset",
532 "xyz.openbmc_project.Inventory.Item.Cpu",
533 "xyz.openbmc_project.Inventory.Item.Dimm",
534 "xyz.openbmc_project.Inventory.Item.System",
535 "xyz.openbmc_project.Common.UUID",
536 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700537}
538
539/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700540 * @brief Retrieves host state properties over dbus
541 *
542 * @param[in] aResp Shared pointer for completing asynchronous calls.
543 *
544 * @return None.
545 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800546inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700547{
548 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700549 sdbusplus::asio::getProperty<std::string>(
550 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
551 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
552 "CurrentHostState",
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800553 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700554 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700555 if (ec)
556 {
557 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700558 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700559 // Service not available, no error, just don't return
560 // host state info
561 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700562 return;
563 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700564 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
565 messages::internalError(aResp->res);
566 return;
567 }
Ed Tanous66173382018-08-15 18:20:59 -0700568
Ed Tanous002d39b2022-05-31 08:59:27 -0700569 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
570 // Verify Host State
571 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
572 {
573 aResp->res.jsonValue["PowerState"] = "On";
574 aResp->res.jsonValue["Status"]["State"] = "Enabled";
575 }
576 else if (hostState ==
577 "xyz.openbmc_project.State.Host.HostState.Quiesced")
578 {
579 aResp->res.jsonValue["PowerState"] = "On";
580 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
581 }
582 else if (hostState ==
583 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
584 {
585 aResp->res.jsonValue["PowerState"] = "On";
586 aResp->res.jsonValue["Status"]["State"] = "InTest";
587 }
588 else if (
589 hostState ==
590 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
591 {
592 aResp->res.jsonValue["PowerState"] = "PoweringOn";
593 aResp->res.jsonValue["Status"]["State"] = "Starting";
594 }
595 else if (hostState ==
596 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
597 {
598 aResp->res.jsonValue["PowerState"] = "PoweringOff";
599 aResp->res.jsonValue["Status"]["State"] = "Disabled";
600 }
601 else
602 {
603 aResp->res.jsonValue["PowerState"] = "Off";
604 aResp->res.jsonValue["Status"]["State"] = "Disabled";
605 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700606 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700607}
608
609/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500610 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530611 *
612 * @param[in] dbusSource The boot source in DBUS speak.
613 *
614 * @return Returns as a string, the boot source in Redfish terms. If translation
615 * cannot be done, returns an empty string.
616 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000617inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530618{
619 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
620 {
621 return "None";
622 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700623 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530624 {
625 return "Hdd";
626 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700627 if (dbusSource ==
628 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530629 {
630 return "Cd";
631 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700632 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530633 {
634 return "Pxe";
635 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700636 if (dbusSource ==
637 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700638 {
639 return "Usb";
640 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700641 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530642}
643
644/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300645 * @brief Translates boot type DBUS property value to redfish.
646 *
647 * @param[in] dbusType The boot type in DBUS speak.
648 *
649 * @return Returns as a string, the boot type in Redfish terms. If translation
650 * cannot be done, returns an empty string.
651 */
652inline std::string dbusToRfBootType(const std::string& dbusType)
653{
654 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
655 {
656 return "Legacy";
657 }
658 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
659 {
660 return "UEFI";
661 }
662 return "";
663}
664
665/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500666 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530667 *
668 * @param[in] dbusMode The boot mode in DBUS speak.
669 *
670 * @return Returns as a string, the boot mode in Redfish terms. If translation
671 * cannot be done, returns an empty string.
672 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000673inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530674{
675 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
676 {
677 return "None";
678 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700679 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530680 {
681 return "Diags";
682 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700683 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530684 {
685 return "BiosSetup";
686 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700687 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530688}
689
690/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600691 * @brief Translates boot progress DBUS property value to redfish.
692 *
693 * @param[in] dbusBootProgress The boot progress in DBUS speak.
694 *
695 * @return Returns as a string, the boot progress in Redfish terms. If
696 * translation cannot be done, returns "None".
697 */
698inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
699{
700 // Now convert the D-Bus BootProgress to the appropriate Redfish
701 // enum
702 std::string rfBpLastState = "None";
703 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
704 "ProgressStages.Unspecified")
705 {
706 rfBpLastState = "None";
707 }
708 else if (dbusBootProgress ==
709 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
710 "PrimaryProcInit")
711 {
712 rfBpLastState = "PrimaryProcessorInitializationStarted";
713 }
714 else if (dbusBootProgress ==
715 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
716 "BusInit")
717 {
718 rfBpLastState = "BusInitializationStarted";
719 }
720 else if (dbusBootProgress ==
721 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
722 "MemoryInit")
723 {
724 rfBpLastState = "MemoryInitializationStarted";
725 }
726 else if (dbusBootProgress ==
727 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
728 "SecondaryProcInit")
729 {
730 rfBpLastState = "SecondaryProcessorInitializationStarted";
731 }
732 else if (dbusBootProgress ==
733 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
734 "PCIInit")
735 {
736 rfBpLastState = "PCIResourceConfigStarted";
737 }
738 else if (dbusBootProgress ==
739 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
740 "SystemSetup")
741 {
742 rfBpLastState = "SetupEntered";
743 }
744 else if (dbusBootProgress ==
745 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
746 "SystemInitComplete")
747 {
748 rfBpLastState = "SystemHardwareInitializationComplete";
749 }
750 else if (dbusBootProgress ==
751 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
752 "OSStart")
753 {
754 rfBpLastState = "OSBootStarted";
755 }
756 else if (dbusBootProgress ==
757 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
758 "OSRunning")
759 {
760 rfBpLastState = "OSRunning";
761 }
762 else
763 {
764 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
765 << dbusBootProgress;
766 // Just return the default
767 }
768 return rfBpLastState;
769}
770
771/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500772 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530773 *
774 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700775 * @param[out] bootSource The DBus source
776 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530777 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700778 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530779 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800780inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500781 const std::string& rfSource,
782 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530783{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300784 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
785 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700786
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530787 if (rfSource == "None")
788 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700789 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530790 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700791 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530792 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700793 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
794 }
795 else if (rfSource == "Hdd")
796 {
797 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
798 }
799 else if (rfSource == "Diags")
800 {
801 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
802 }
803 else if (rfSource == "Cd")
804 {
805 bootSource =
806 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
807 }
808 else if (rfSource == "BiosSetup")
809 {
810 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530811 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700812 else if (rfSource == "Usb")
813 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700814 bootSource =
815 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700816 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530817 else
818 {
George Liu0fda0f12021-11-16 10:06:17 +0800819 BMCWEB_LOG_DEBUG
820 << "Invalid property value for BootSourceOverrideTarget: "
821 << bootSource;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700822 messages::propertyValueNotInList(aResp->res, rfSource,
823 "BootSourceTargetOverride");
824 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530825 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700826 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530827}
Ali Ahmed19817712021-06-29 17:01:52 -0500828
Andrew Geissler978b8802020-11-19 13:36:40 -0600829/**
830 * @brief Retrieves boot progress of the system
831 *
832 * @param[in] aResp Shared pointer for generating response message.
833 *
834 * @return None.
835 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800836inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600837{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700838 sdbusplus::asio::getProperty<std::string>(
839 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
840 "/xyz/openbmc_project/state/host0",
841 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Andrew Geissler978b8802020-11-19 13:36:40 -0600842 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700843 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700844 if (ec)
845 {
846 // BootProgress is an optional object so just do nothing if
847 // not found
848 return;
849 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600850
Ed Tanous002d39b2022-05-31 08:59:27 -0700851 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600852
Ed Tanous002d39b2022-05-31 08:59:27 -0700853 aResp->res.jsonValue["BootProgress"]["LastState"] =
854 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700855 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600856}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530857
858/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000859 * @brief Retrieves boot progress Last Update of the system
860 *
861 * @param[in] aResp Shared pointer for generating response message.
862 *
863 * @return None.
864 */
865inline void getBootProgressLastStateTime(
866 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
867{
868 sdbusplus::asio::getProperty<uint64_t>(
869 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
870 "/xyz/openbmc_project/state/host0",
871 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
872 [aResp](const boost::system::error_code ec,
873 const uint64_t lastStateTime) {
874 if (ec)
875 {
876 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
877 return;
878 }
879
880 // BootProgressLastUpdate is the last time the BootProgress property
881 // was updated. The time is the Epoch time, number of microseconds
882 // since 1 Jan 1970 00::00::00 UTC."
883 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
884 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
885
886 // Convert to ISO 8601 standard
887 aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
888 redfish::time_utils::getDateTimeUintUs(lastStateTime);
889 });
890}
891
892/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300893 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300894 *
895 * @param[in] aResp Shared pointer for generating response message.
896 *
897 * @return None.
898 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300899
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300900inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300901{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700902 sdbusplus::asio::getProperty<std::string>(
903 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
904 "/xyz/openbmc_project/control/host0/boot",
905 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300906 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700907 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700908 if (ec)
909 {
910 // not an error, don't have to have the interface
911 return;
912 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300913
Ed Tanous002d39b2022-05-31 08:59:27 -0700914 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300915
Ed Tanous002d39b2022-05-31 08:59:27 -0700916 aResp->res.jsonValue["Boot"]
917 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700918 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300919
Ed Tanous002d39b2022-05-31 08:59:27 -0700920 auto rfType = dbusToRfBootType(bootType);
921 if (rfType.empty())
922 {
923 messages::internalError(aResp->res);
924 return;
925 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300926
Ed Tanous002d39b2022-05-31 08:59:27 -0700927 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700928 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300929}
930
931/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300932 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530933 *
934 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530935 *
936 * @return None.
937 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300938
939inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530940{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700941 sdbusplus::asio::getProperty<std::string>(
942 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
943 "/xyz/openbmc_project/control/host0/boot",
944 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300945 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700946 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700947 if (ec)
948 {
949 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
950 messages::internalError(aResp->res);
951 return;
952 }
953
954 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
955
956 aResp->res
957 .jsonValue["Boot"]
958 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
959 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
960
961 if (bootModeStr !=
962 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
963 {
964 auto rfMode = dbusToRfBootMode(bootModeStr);
965 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530966 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700967 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
968 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530969 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700970 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700971 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530972}
973
974/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300975 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530976 *
977 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530978 *
979 * @return None.
980 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300981
982inline void
983 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530984{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700985 sdbusplus::asio::getProperty<std::string>(
986 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
987 "/xyz/openbmc_project/control/host0/boot",
988 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300989 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700990 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700991 if (ec)
992 {
993 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +0000994 if (ec.value() == boost::asio::error::host_unreachable)
995 {
996 return;
997 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700998 messages::internalError(aResp->res);
999 return;
1000 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301001
Ed Tanous002d39b2022-05-31 08:59:27 -07001002 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301003
Ed Tanous002d39b2022-05-31 08:59:27 -07001004 auto rfSource = dbusToRfBootSource(bootSourceStr);
1005 if (!rfSource.empty())
1006 {
1007 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1008 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001009
Ed Tanous002d39b2022-05-31 08:59:27 -07001010 // Get BootMode as BootSourceOverrideTarget is constructed
1011 // from both BootSource and BootMode
1012 getBootOverrideMode(aResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001013 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301014}
1015
1016/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001017 * @brief This functions abstracts all the logic behind getting a
1018 * "BootSourceOverrideEnabled" property from an overall boot override enable
1019 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301020 *
1021 * @param[in] aResp Shared pointer for generating response message.
1022 *
1023 * @return None.
1024 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301025
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001026inline void
1027 processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1028 const bool bootOverrideEnableSetting)
1029{
1030 if (!bootOverrideEnableSetting)
1031 {
1032 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1033 return;
1034 }
1035
1036 // If boot source override is enabled, we need to check 'one_time'
1037 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001038 sdbusplus::asio::getProperty<bool>(
1039 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1040 "/xyz/openbmc_project/control/host0/boot/one_time",
1041 "xyz.openbmc_project.Object.Enable", "Enabled",
1042 [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001043 if (ec)
1044 {
1045 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1046 messages::internalError(aResp->res);
1047 return;
1048 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301049
Ed Tanous002d39b2022-05-31 08:59:27 -07001050 if (oneTimeSetting)
1051 {
1052 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1053 }
1054 else
1055 {
1056 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1057 "Continuous";
1058 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001059 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301060}
1061
1062/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001063 * @brief Retrieves boot override enable over DBUS
1064 *
1065 * @param[in] aResp Shared pointer for generating response message.
1066 *
1067 * @return None.
1068 */
1069
1070inline void
1071 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1072{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001073 sdbusplus::asio::getProperty<bool>(
1074 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1075 "/xyz/openbmc_project/control/host0/boot",
1076 "xyz.openbmc_project.Object.Enable", "Enabled",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001077 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001078 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001079 if (ec)
1080 {
1081 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001082 if (ec.value() == boost::asio::error::host_unreachable)
1083 {
1084 return;
1085 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001086 messages::internalError(aResp->res);
1087 return;
1088 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001089
Ed Tanous002d39b2022-05-31 08:59:27 -07001090 processBootOverrideEnable(aResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001091 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001092}
1093
1094/**
1095 * @brief Retrieves boot source override properties
1096 *
1097 * @param[in] aResp Shared pointer for generating response message.
1098 *
1099 * @return None.
1100 */
1101inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1102{
1103 BMCWEB_LOG_DEBUG << "Get boot information.";
1104
1105 getBootOverrideSource(aResp);
1106 getBootOverrideType(aResp);
1107 getBootOverrideEnable(aResp);
1108}
1109
1110/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001111 * @brief Retrieves the Last Reset Time
1112 *
1113 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1114 * and power off. Even though this is the "system" Redfish object look at the
1115 * chassis D-Bus interface for the LastStateChangeTime since this has the
1116 * last power operation time.
1117 *
1118 * @param[in] aResp Shared pointer for generating response message.
1119 *
1120 * @return None.
1121 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001122inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001123{
1124 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1125
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001126 sdbusplus::asio::getProperty<uint64_t>(
1127 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1128 "/xyz/openbmc_project/state/chassis0",
1129 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1130 [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001131 if (ec)
1132 {
1133 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1134 return;
1135 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001136
Ed Tanous002d39b2022-05-31 08:59:27 -07001137 // LastStateChangeTime is epoch time, in milliseconds
1138 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1139 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001140
Ed Tanous002d39b2022-05-31 08:59:27 -07001141 // Convert to ISO 8601 standard
1142 aResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001143 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001144 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001145}
1146
1147/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001148 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1149 *
1150 * @param[in] aResp Shared pointer for generating response message.
1151 *
1152 * @return None.
1153 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001154inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001155{
1156 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1157
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001158 sdbusplus::asio::getProperty<bool>(
1159 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1160 "/xyz/openbmc_project/control/host0/auto_reboot",
1161 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1162 [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001163 if (ec)
1164 {
1165 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1166 return;
1167 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001168
Ed Tanous002d39b2022-05-31 08:59:27 -07001169 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1170 if (autoRebootEnabled)
1171 {
1172 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1173 "RetryAttempts";
1174 // If AutomaticRetry (AutoReboot) is enabled see how many
1175 // attempts are left
1176 sdbusplus::asio::getProperty<uint32_t>(
1177 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1178 "/xyz/openbmc_project/state/host0",
1179 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1180 "AttemptsLeft",
1181 [aResp](const boost::system::error_code ec2,
1182 const uint32_t autoRebootAttemptsLeft) {
1183 if (ec2)
1184 {
1185 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
1186 return;
1187 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001188
Ed Tanous002d39b2022-05-31 08:59:27 -07001189 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1190 << autoRebootAttemptsLeft;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001191
Ed Tanous002d39b2022-05-31 08:59:27 -07001192 aResp->res
1193 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1194 autoRebootAttemptsLeft;
1195 });
1196 }
1197 else
1198 {
1199 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
1200 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001201
Ed Tanous002d39b2022-05-31 08:59:27 -07001202 // Not on D-Bus. Hardcoded here:
1203 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1204 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001205
Ed Tanous002d39b2022-05-31 08:59:27 -07001206 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1207 // and RetryAttempts. OpenBMC only supports Disabled and
1208 // RetryAttempts.
1209 aResp->res.jsonValue["Boot"]
1210 ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
1211 "Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001212 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001213}
1214
1215/**
George Liuc6a620f2020-04-10 17:18:11 +08001216 * @brief Retrieves power restore policy over DBUS.
1217 *
1218 * @param[in] aResp Shared pointer for generating response message.
1219 *
1220 * @return None.
1221 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001222inline void
1223 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001224{
1225 BMCWEB_LOG_DEBUG << "Get power restore policy";
1226
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001227 sdbusplus::asio::getProperty<std::string>(
1228 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1229 "/xyz/openbmc_project/control/host0/power_restore_policy",
1230 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1231 [aResp](const boost::system::error_code ec, const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001232 if (ec)
1233 {
1234 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1235 return;
1236 }
George Liuc6a620f2020-04-10 17:18:11 +08001237
Ed Tanous002d39b2022-05-31 08:59:27 -07001238 const boost::container::flat_map<std::string, std::string> policyMaps = {
1239 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1240 "AlwaysOn"},
1241 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1242 "AlwaysOff"},
1243 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1244 "LastState"},
1245 // Return `AlwaysOff` when power restore policy set to "None"
1246 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
1247 "AlwaysOff"}};
George Liuc6a620f2020-04-10 17:18:11 +08001248
Ed Tanous002d39b2022-05-31 08:59:27 -07001249 auto policyMapsIt = policyMaps.find(policy);
1250 if (policyMapsIt == policyMaps.end())
1251 {
1252 messages::internalError(aResp->res);
1253 return;
1254 }
George Liuc6a620f2020-04-10 17:18:11 +08001255
Ed Tanous002d39b2022-05-31 08:59:27 -07001256 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001257 });
George Liuc6a620f2020-04-10 17:18:11 +08001258}
1259
1260/**
Ali Ahmed19817712021-06-29 17:01:52 -05001261 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1262 * TPM is required for booting the host.
1263 *
1264 * @param[in] aResp Shared pointer for generating response message.
1265 *
1266 * @return None.
1267 */
1268inline void getTrustedModuleRequiredToBoot(
1269 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1270{
1271 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1272
1273 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001274 [aResp](const boost::system::error_code ec,
1275 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001276 if (ec)
1277 {
1278 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1279 << ec;
1280 // This is an optional D-Bus object so just return if
1281 // error occurs
1282 return;
1283 }
1284 if (subtree.empty())
1285 {
1286 // As noted above, this is an optional interface so just return
1287 // if there is no instance found
1288 return;
1289 }
1290
1291 /* When there is more than one TPMEnable object... */
1292 if (subtree.size() > 1)
1293 {
1294 BMCWEB_LOG_DEBUG
1295 << "DBUS response has more than 1 TPM Enable object:"
1296 << subtree.size();
1297 // Throw an internal Error and return
1298 messages::internalError(aResp->res);
1299 return;
1300 }
1301
1302 // Make sure the Dbus response map has a service and objectPath
1303 // field
1304 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1305 {
1306 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1307 messages::internalError(aResp->res);
1308 return;
1309 }
1310
1311 const std::string& path = subtree[0].first;
1312 const std::string& serv = subtree[0].second.begin()->first;
1313
1314 // Valid TPM Enable object found, now reading the current value
1315 sdbusplus::asio::getProperty<bool>(
1316 *crow::connections::systemBus, serv, path,
1317 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanous8a592812022-06-04 09:06:59 -07001318 [aResp](const boost::system::error_code ec2, bool tpmRequired) {
1319 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001320 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001321 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001322 << ec2;
Ali Ahmed19817712021-06-29 17:01:52 -05001323 messages::internalError(aResp->res);
1324 return;
1325 }
1326
Ed Tanous002d39b2022-05-31 08:59:27 -07001327 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001328 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001329 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1330 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001331 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001332 else
1333 {
1334 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1335 "Disabled";
1336 }
1337 });
Ali Ahmed19817712021-06-29 17:01:52 -05001338 },
1339 "xyz.openbmc_project.ObjectMapper",
1340 "/xyz/openbmc_project/object_mapper",
1341 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1342 std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1343}
1344
1345/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001346 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1347 * TPM is required for booting the host.
1348 *
1349 * @param[in] aResp Shared pointer for generating response message.
1350 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1351 *
1352 * @return None.
1353 */
1354inline void setTrustedModuleRequiredToBoot(
1355 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
1356{
1357 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1358
1359 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001360 [aResp, tpmRequired](const boost::system::error_code ec,
1361 dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001362 if (ec)
1363 {
1364 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1365 << ec;
1366 messages::internalError(aResp->res);
1367 return;
1368 }
1369 if (subtree.empty())
1370 {
1371 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
1372 "TrustedModuleRequiredToBoot");
1373 return;
1374 }
1375
1376 /* When there is more than one TPMEnable object... */
1377 if (subtree.size() > 1)
1378 {
1379 BMCWEB_LOG_DEBUG
1380 << "DBUS response has more than 1 TPM Enable object:"
1381 << subtree.size();
1382 // Throw an internal Error and return
1383 messages::internalError(aResp->res);
1384 return;
1385 }
1386
1387 // Make sure the Dbus response map has a service and objectPath
1388 // field
1389 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1390 {
1391 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1392 messages::internalError(aResp->res);
1393 return;
1394 }
1395
1396 const std::string& path = subtree[0].first;
1397 const std::string& serv = subtree[0].second.begin()->first;
1398
1399 if (serv.empty())
1400 {
1401 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1402 messages::internalError(aResp->res);
1403 return;
1404 }
1405
1406 // Valid TPM Enable object found, now setting the value
1407 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07001408 [aResp](const boost::system::error_code ec2) {
1409 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001410 {
1411 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001412 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001413 << ec2;
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001414 messages::internalError(aResp->res);
1415 return;
1416 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001417 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1418 },
1419 serv, path, "org.freedesktop.DBus.Properties", "Set",
1420 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1421 dbus::utility::DbusVariantType(tpmRequired));
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001422 },
1423 "xyz.openbmc_project.ObjectMapper",
1424 "/xyz/openbmc_project/object_mapper",
1425 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1426 std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1427}
1428
1429/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301430 * @brief Sets boot properties into DBUS object(s).
1431 *
1432 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001433 * @param[in] bootType The boot type to set.
1434 * @return Integer error code.
1435 */
1436inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001437 const std::optional<std::string>& bootType)
1438{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001439 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001440
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001441 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001442 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001443 return;
1444 }
1445
1446 // Source target specified
1447 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1448 // Figure out which DBUS interface and property to use
1449 if (*bootType == "Legacy")
1450 {
1451 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1452 }
1453 else if (*bootType == "UEFI")
1454 {
1455 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1456 }
1457 else
1458 {
1459 BMCWEB_LOG_DEBUG << "Invalid property value for "
1460 "BootSourceOverrideMode: "
1461 << *bootType;
1462 messages::propertyValueNotInList(aResp->res, *bootType,
1463 "BootSourceOverrideMode");
1464 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001465 }
1466
1467 // Act on validated parameters
1468 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1469
1470 crow::connections::systemBus->async_method_call(
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001471 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001472 if (ec)
1473 {
1474 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1475 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001476 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001477 messages::resourceNotFound(aResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001478 return;
1479 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001480 messages::internalError(aResp->res);
1481 return;
1482 }
1483 BMCWEB_LOG_DEBUG << "Boot type update done.";
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001484 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001485 "xyz.openbmc_project.Settings",
1486 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001487 "org.freedesktop.DBus.Properties", "Set",
1488 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001489 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001490}
1491
1492/**
1493 * @brief Sets boot properties into DBUS object(s).
1494 *
1495 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001496 * @param[in] bootType The boot type to set.
1497 * @return Integer error code.
1498 */
1499inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1500 const std::optional<std::string>& bootEnable)
1501{
1502 if (!bootEnable)
1503 {
1504 return;
1505 }
1506 // Source target specified
1507 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1508
1509 bool bootOverrideEnable = false;
1510 bool bootOverridePersistent = false;
1511 // Figure out which DBUS interface and property to use
1512 if (*bootEnable == "Disabled")
1513 {
1514 bootOverrideEnable = false;
1515 }
1516 else if (*bootEnable == "Once")
1517 {
1518 bootOverrideEnable = true;
1519 bootOverridePersistent = false;
1520 }
1521 else if (*bootEnable == "Continuous")
1522 {
1523 bootOverrideEnable = true;
1524 bootOverridePersistent = true;
1525 }
1526 else
1527 {
George Liu0fda0f12021-11-16 10:06:17 +08001528 BMCWEB_LOG_DEBUG
1529 << "Invalid property value for BootSourceOverrideEnabled: "
1530 << *bootEnable;
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001531 messages::propertyValueNotInList(aResp->res, *bootEnable,
1532 "BootSourceOverrideEnabled");
1533 return;
1534 }
1535
1536 // Act on validated parameters
1537 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1538
1539 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07001540 [aResp](const boost::system::error_code ec2) {
1541 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001542 {
Ed Tanous8a592812022-06-04 09:06:59 -07001543 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07001544 messages::internalError(aResp->res);
1545 return;
1546 }
1547 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001548 },
1549 "xyz.openbmc_project.Settings",
1550 "/xyz/openbmc_project/control/host0/boot",
1551 "org.freedesktop.DBus.Properties", "Set",
1552 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001553 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001554
1555 if (!bootOverrideEnable)
1556 {
1557 return;
1558 }
1559
1560 // In case boot override is enabled we need to set correct value for the
1561 // 'one_time' enable DBus interface
1562 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1563 << bootOverridePersistent;
1564
1565 crow::connections::systemBus->async_method_call(
1566 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001567 if (ec)
1568 {
1569 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1570 messages::internalError(aResp->res);
1571 return;
1572 }
1573 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001574 },
1575 "xyz.openbmc_project.Settings",
1576 "/xyz/openbmc_project/control/host0/boot/one_time",
1577 "org.freedesktop.DBus.Properties", "Set",
1578 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001579 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001580}
1581
1582/**
1583 * @brief Sets boot properties into DBUS object(s).
1584 *
1585 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301586 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301587 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001588 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301589 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001590inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001591 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301592{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001593 std::string bootSourceStr;
1594 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001595
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001596 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301597 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001598 return;
1599 }
1600
1601 // Source target specified
1602 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1603 // Figure out which DBUS interface and property to use
Ed Tanouse662eae2022-01-25 10:39:19 -08001604 if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1605 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001606 {
1607 BMCWEB_LOG_DEBUG
1608 << "Invalid property value for BootSourceOverrideTarget: "
1609 << *bootSource;
1610 messages::propertyValueNotInList(aResp->res, *bootSource,
1611 "BootSourceTargetOverride");
1612 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001613 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301614
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001615 // Act on validated parameters
1616 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1617 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001618
1619 crow::connections::systemBus->async_method_call(
1620 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001621 if (ec)
1622 {
1623 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1624 messages::internalError(aResp->res);
1625 return;
1626 }
1627 BMCWEB_LOG_DEBUG << "Boot source update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001628 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001629 "xyz.openbmc_project.Settings",
1630 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001631 "org.freedesktop.DBus.Properties", "Set",
1632 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001633 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001634
1635 crow::connections::systemBus->async_method_call(
1636 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001637 if (ec)
1638 {
1639 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1640 messages::internalError(aResp->res);
1641 return;
1642 }
1643 BMCWEB_LOG_DEBUG << "Boot mode update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001644 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001645 "xyz.openbmc_project.Settings",
1646 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001647 "org.freedesktop.DBus.Properties", "Set",
1648 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001649 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001650}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001651
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001652/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001653 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301654 *
1655 * @param[in] aResp Shared pointer for generating response message.
1656 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001657 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301658 * @param[in] bootEnable The boot override enable from incoming RF request.
1659 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001660 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301661 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001662
1663inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1664 const std::optional<std::string>& bootSource,
1665 const std::optional<std::string>& bootType,
1666 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301667{
1668 BMCWEB_LOG_DEBUG << "Set boot information.";
1669
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001670 setBootModeOrSource(aResp, bootSource);
1671 setBootType(aResp, bootType);
1672 setBootEnable(aResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301673}
1674
George Liuc6a620f2020-04-10 17:18:11 +08001675/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001676 * @brief Sets AssetTag
1677 *
1678 * @param[in] aResp Shared pointer for generating response message.
1679 * @param[in] assetTag "AssetTag" from request.
1680 *
1681 * @return None.
1682 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001683inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001684 const std::string& assetTag)
1685{
1686 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001687 [aResp,
1688 assetTag](const boost::system::error_code ec,
1689 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001690 if (ec)
1691 {
1692 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1693 messages::internalError(aResp->res);
1694 return;
1695 }
1696 if (subtree.empty())
1697 {
1698 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1699 messages::internalError(aResp->res);
1700 return;
1701 }
1702 // Assume only 1 system D-Bus object
1703 // Throw an error if there is more than 1
1704 if (subtree.size() > 1)
1705 {
1706 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1707 messages::internalError(aResp->res);
1708 return;
1709 }
1710 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1711 {
1712 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1713 messages::internalError(aResp->res);
1714 return;
1715 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001716
Ed Tanous002d39b2022-05-31 08:59:27 -07001717 const std::string& path = subtree[0].first;
1718 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001719
Ed Tanous002d39b2022-05-31 08:59:27 -07001720 if (service.empty())
1721 {
1722 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1723 messages::internalError(aResp->res);
1724 return;
1725 }
1726
1727 crow::connections::systemBus->async_method_call(
1728 [aResp](const boost::system::error_code ec2) {
1729 if (ec2)
Gunnar Mills98e386e2020-10-30 14:58:09 -05001730 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001731 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1732 << ec2;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001733 messages::internalError(aResp->res);
1734 return;
1735 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001736 },
1737 service, path, "org.freedesktop.DBus.Properties", "Set",
1738 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1739 dbus::utility::DbusVariantType(assetTag));
Gunnar Mills98e386e2020-10-30 14:58:09 -05001740 },
1741 "xyz.openbmc_project.ObjectMapper",
1742 "/xyz/openbmc_project/object_mapper",
1743 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
1744 "/xyz/openbmc_project/inventory", int32_t(0),
1745 std::array<const char*, 1>{
1746 "xyz.openbmc_project.Inventory.Item.System"});
1747}
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(
1783 [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(
1832 [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",
AppaRao Pulia6349912019-10-18 17:16:08 +05301860 [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:
1966 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001967 [aResp](const boost::system::error_code ec,
1968 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001969 if (ec)
1970 {
1971 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1972 << ec;
1973 // This is an optional D-Bus object so just return if
1974 // error occurs
1975 return;
1976 }
1977 if (subtree.empty())
1978 {
1979 // As noted above, this is an optional interface so just return
1980 // if there is no instance found
1981 return;
1982 }
1983 if (subtree.size() > 1)
1984 {
1985 // More then one PowerMode object is not supported and is an
1986 // error
1987 BMCWEB_LOG_DEBUG
1988 << "Found more than 1 system D-Bus Power.Mode objects: "
1989 << subtree.size();
1990 messages::internalError(aResp->res);
1991 return;
1992 }
1993 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
1994 {
1995 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
1996 messages::internalError(aResp->res);
1997 return;
1998 }
1999 const std::string& path = subtree[0].first;
2000 const std::string& service = subtree[0].second.begin()->first;
2001 if (service.empty())
2002 {
2003 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2004 messages::internalError(aResp->res);
2005 return;
2006 }
2007 // Valid Power Mode object found, now read the current value
2008 sdbusplus::asio::getProperty<std::string>(
2009 *crow::connections::systemBus, service, path,
2010 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanous8a592812022-06-04 09:06:59 -07002011 [aResp](const boost::system::error_code ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002012 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002013 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002014 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002015 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002016 << ec2;
Chris Cain3a2d04242021-05-28 16:57:10 -05002017 messages::internalError(aResp->res);
2018 return;
2019 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002020
Ed Tanous002d39b2022-05-31 08:59:27 -07002021 aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2022 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002023
Ed Tanous002d39b2022-05-31 08:59:27 -07002024 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2025 translatePowerMode(aResp, pmode);
2026 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002027 },
2028 "xyz.openbmc_project.ObjectMapper",
2029 "/xyz/openbmc_project/object_mapper",
2030 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2031 std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
2032}
2033
2034/**
2035 * @brief Validate the specified mode is valid and return the PowerMode
2036 * name associated with that string
2037 *
2038 * @param[in] aResp Shared pointer for generating response message.
2039 * @param[in] modeString String representing the desired PowerMode
2040 *
2041 * @return PowerMode value or empty string if mode is not valid
2042 */
2043inline std::string
2044 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2045 const std::string& modeString)
2046{
2047 std::string mode;
2048
2049 if (modeString == "Static")
2050 {
2051 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2052 }
2053 else if (modeString == "MaximumPerformance")
2054 {
George Liu0fda0f12021-11-16 10:06:17 +08002055 mode =
2056 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002057 }
2058 else if (modeString == "PowerSaving")
2059 {
2060 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2061 }
2062 else
2063 {
2064 messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
2065 }
2066 return mode;
2067}
2068
2069/**
2070 * @brief Sets system power mode.
2071 *
2072 * @param[in] aResp Shared pointer for generating response message.
2073 * @param[in] pmode System power mode from request.
2074 *
2075 * @return None.
2076 */
2077inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2078 const std::string& pmode)
2079{
2080 BMCWEB_LOG_DEBUG << "Set power mode.";
2081
2082 std::string powerMode = validatePowerMode(aResp, pmode);
2083 if (powerMode.empty())
2084 {
2085 return;
2086 }
2087
2088 // Get Power Mode object path:
2089 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08002090 [aResp,
2091 powerMode](const boost::system::error_code ec,
2092 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002093 if (ec)
2094 {
2095 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2096 << ec;
2097 // This is an optional D-Bus object, but user attempted to patch
2098 messages::internalError(aResp->res);
2099 return;
2100 }
2101 if (subtree.empty())
2102 {
2103 // This is an optional D-Bus object, but user attempted to patch
2104 messages::resourceNotFound(aResp->res, "ComputerSystem",
2105 "PowerMode");
2106 return;
2107 }
2108 if (subtree.size() > 1)
2109 {
2110 // More then one PowerMode object is not supported and is an
2111 // error
2112 BMCWEB_LOG_DEBUG
2113 << "Found more than 1 system D-Bus Power.Mode objects: "
2114 << subtree.size();
2115 messages::internalError(aResp->res);
2116 return;
2117 }
2118 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2119 {
2120 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2121 messages::internalError(aResp->res);
2122 return;
2123 }
2124 const std::string& path = subtree[0].first;
2125 const std::string& service = subtree[0].second.begin()->first;
2126 if (service.empty())
2127 {
2128 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2129 messages::internalError(aResp->res);
2130 return;
2131 }
2132
2133 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2134 << path;
2135
2136 // Set the Power Mode property
2137 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002138 [aResp](const boost::system::error_code ec2) {
2139 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002140 {
Chris Cain3a2d04242021-05-28 16:57:10 -05002141 messages::internalError(aResp->res);
2142 return;
2143 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002144 },
2145 service, path, "org.freedesktop.DBus.Properties", "Set",
2146 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2147 dbus::utility::DbusVariantType(powerMode));
Chris Cain3a2d04242021-05-28 16:57:10 -05002148 },
2149 "xyz.openbmc_project.ObjectMapper",
2150 "/xyz/openbmc_project/object_mapper",
2151 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2152 std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
2153}
2154
2155/**
Yong Li51709ff2019-09-30 14:13:04 +08002156 * @brief Translates watchdog timeout action DBUS property value to redfish.
2157 *
2158 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2159 *
2160 * @return Returns as a string, the timeout action in Redfish terms. If
2161 * translation cannot be done, returns an empty string.
2162 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002163inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002164{
2165 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2166 {
2167 return "None";
2168 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002169 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002170 {
2171 return "ResetSystem";
2172 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002173 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002174 {
2175 return "PowerDown";
2176 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002177 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002178 {
2179 return "PowerCycle";
2180 }
2181
2182 return "";
2183}
2184
2185/**
Yong Lic45f0082019-10-10 14:19:01 +08002186 *@brief Translates timeout action from Redfish to DBUS property value.
2187 *
2188 *@param[in] rfAction The timeout action in Redfish.
2189 *
2190 *@return Returns as a string, the time_out action as expected by DBUS.
2191 *If translation cannot be done, returns an empty string.
2192 */
2193
Ed Tanous23a21a12020-07-25 04:45:05 +00002194inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002195{
2196 if (rfAction == "None")
2197 {
2198 return "xyz.openbmc_project.State.Watchdog.Action.None";
2199 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002200 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002201 {
2202 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2203 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002204 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002205 {
2206 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2207 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002208 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002209 {
2210 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2211 }
2212
2213 return "";
2214}
2215
2216/**
Yong Li51709ff2019-09-30 14:13:04 +08002217 * @brief Retrieves host watchdog timer properties over DBUS
2218 *
2219 * @param[in] aResp Shared pointer for completing asynchronous calls.
2220 *
2221 * @return None.
2222 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002223inline void
2224 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08002225{
2226 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002227 sdbusplus::asio::getAllProperties(
2228 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2229 "/xyz/openbmc_project/watchdog/host0",
2230 "xyz.openbmc_project.State.Watchdog",
Yong Li51709ff2019-09-30 14:13:04 +08002231 [aResp](const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002232 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002233 if (ec)
2234 {
2235 // watchdog service is stopped
2236 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2237 return;
2238 }
2239
2240 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2241
2242 nlohmann::json& hostWatchdogTimer =
2243 aResp->res.jsonValue["HostWatchdogTimer"];
2244
2245 // watchdog service is running/enabled
2246 hostWatchdogTimer["Status"]["State"] = "Enabled";
2247
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002248 const bool* enabled = nullptr;
2249 const std::string* expireAction = nullptr;
2250
2251 const bool success = sdbusplus::unpackPropertiesNoThrow(
2252 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2253 "ExpireAction", expireAction);
2254
2255 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002256 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002257 messages::internalError(aResp->res);
2258 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002259 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002260
2261 if (enabled != nullptr)
2262 {
2263 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2264 }
2265
2266 if (expireAction != nullptr)
2267 {
2268 std::string action = dbusToRfWatchdogAction(*expireAction);
2269 if (action.empty())
2270 {
2271 messages::internalError(aResp->res);
2272 return;
2273 }
2274 hostWatchdogTimer["TimeoutAction"] = action;
2275 }
2276 });
Yong Li51709ff2019-09-30 14:13:04 +08002277}
2278
2279/**
Yong Lic45f0082019-10-10 14:19:01 +08002280 * @brief Sets Host WatchDog Timer properties.
2281 *
2282 * @param[in] aResp Shared pointer for generating response message.
2283 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2284 * RF request.
2285 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2286 *
2287 * @return None.
2288 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002289inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08002290 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002291 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002292{
2293 BMCWEB_LOG_DEBUG << "Set host watchdog";
2294
2295 if (wdtTimeOutAction)
2296 {
2297 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2298 // check if TimeOut Action is Valid
2299 if (wdtTimeOutActStr.empty())
2300 {
2301 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2302 << *wdtTimeOutAction;
2303 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2304 "TimeoutAction");
2305 return;
2306 }
2307
2308 crow::connections::systemBus->async_method_call(
2309 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002310 if (ec)
2311 {
2312 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2313 messages::internalError(aResp->res);
2314 return;
2315 }
Yong Lic45f0082019-10-10 14:19:01 +08002316 },
2317 "xyz.openbmc_project.Watchdog",
2318 "/xyz/openbmc_project/watchdog/host0",
2319 "org.freedesktop.DBus.Properties", "Set",
2320 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002321 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002322 }
2323
2324 if (wdtEnable)
2325 {
2326 crow::connections::systemBus->async_method_call(
2327 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002328 if (ec)
2329 {
2330 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2331 messages::internalError(aResp->res);
2332 return;
2333 }
Yong Lic45f0082019-10-10 14:19:01 +08002334 },
2335 "xyz.openbmc_project.Watchdog",
2336 "/xyz/openbmc_project/watchdog/host0",
2337 "org.freedesktop.DBus.Properties", "Set",
2338 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002339 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002340 }
2341}
2342
Chris Cain37bbf982021-09-20 10:53:09 -05002343/**
2344 * @brief Parse the Idle Power Saver properties into json
2345 *
2346 * @param[in] aResp Shared pointer for completing asynchronous calls.
2347 * @param[in] properties IPS property data from DBus.
2348 *
2349 * @return true if successful
2350 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002351inline bool
2352 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2353 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002354{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002355 const bool* enabled = nullptr;
2356 const uint8_t* enterUtilizationPercent = nullptr;
2357 const uint64_t* enterDwellTime = nullptr;
2358 const uint8_t* exitUtilizationPercent = nullptr;
2359 const uint64_t* exitDwellTime = nullptr;
2360
2361 const bool success = sdbusplus::unpackPropertiesNoThrow(
2362 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2363 "EnterUtilizationPercent", enterUtilizationPercent,
2364 "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime",
2365 exitDwellTime);
2366
2367 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002368 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002369 return false;
2370 }
2371
2372 if (enabled != nullptr)
2373 {
2374 aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
2375 }
2376
2377 if (enterUtilizationPercent != nullptr)
2378 {
2379 aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2380 *enterUtilizationPercent;
2381 }
2382
2383 if (enterDwellTime != nullptr)
2384 {
2385 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2386 aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
2387 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2388 .count();
2389 }
2390
2391 if (exitUtilizationPercent != nullptr)
2392 {
2393 aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2394 *exitUtilizationPercent;
2395 }
2396
2397 if (exitDwellTime != nullptr)
2398 {
2399 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2400 aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
2401 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2402 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002403 }
2404
2405 return true;
2406}
2407
2408/**
2409 * @brief Retrieves host watchdog timer properties over DBUS
2410 *
2411 * @param[in] aResp Shared pointer for completing asynchronous calls.
2412 *
2413 * @return None.
2414 */
2415inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
2416{
2417 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2418
2419 // Get IdlePowerSaver object path:
2420 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08002421 [aResp](const boost::system::error_code ec,
2422 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002423 if (ec)
2424 {
2425 BMCWEB_LOG_DEBUG
2426 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2427 << ec;
2428 messages::internalError(aResp->res);
2429 return;
2430 }
2431 if (subtree.empty())
2432 {
2433 // This is an optional interface so just return
2434 // if there is no instance found
2435 BMCWEB_LOG_DEBUG << "No instances found";
2436 return;
2437 }
2438 if (subtree.size() > 1)
2439 {
2440 // More then one PowerIdlePowerSaver object is not supported and
2441 // is an error
2442 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2443 "Power.IdlePowerSaver objects: "
2444 << subtree.size();
2445 messages::internalError(aResp->res);
2446 return;
2447 }
2448 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2449 {
2450 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2451 messages::internalError(aResp->res);
2452 return;
2453 }
2454 const std::string& path = subtree[0].first;
2455 const std::string& service = subtree[0].second.begin()->first;
2456 if (service.empty())
2457 {
2458 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2459 messages::internalError(aResp->res);
2460 return;
2461 }
2462
2463 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002464 sdbusplus::asio::getAllProperties(
2465 *crow::connections::systemBus, service, path,
2466 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous8a592812022-06-04 09:06:59 -07002467 [aResp](const boost::system::error_code ec2,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002468 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002469 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002470 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002471 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002472 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Chris Cain37bbf982021-09-20 10:53:09 -05002473 messages::internalError(aResp->res);
2474 return;
2475 }
2476
Ed Tanous002d39b2022-05-31 08:59:27 -07002477 if (!parseIpsProperties(aResp, properties))
2478 {
2479 messages::internalError(aResp->res);
2480 return;
2481 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002482 });
Chris Cain37bbf982021-09-20 10:53:09 -05002483 },
2484 "xyz.openbmc_project.ObjectMapper",
2485 "/xyz/openbmc_project/object_mapper",
2486 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2487 std::array<const char*, 1>{
2488 "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
2489
2490 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2491}
2492
2493/**
2494 * @brief Sets Idle Power Saver properties.
2495 *
2496 * @param[in] aResp Shared pointer for generating response message.
2497 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2498 * RF request.
2499 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2500 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2501 * before entering idle state.
2502 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2503 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2504 * before exiting idle state
2505 *
2506 * @return None.
2507 */
2508inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2509 const std::optional<bool> ipsEnable,
2510 const std::optional<uint8_t> ipsEnterUtil,
2511 const std::optional<uint64_t> ipsEnterTime,
2512 const std::optional<uint8_t> ipsExitUtil,
2513 const std::optional<uint64_t> ipsExitTime)
2514{
2515 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2516
2517 // Get IdlePowerSaver object path:
2518 crow::connections::systemBus->async_method_call(
2519 [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002520 ipsExitTime](const boost::system::error_code ec,
2521 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002522 if (ec)
2523 {
2524 BMCWEB_LOG_DEBUG
2525 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2526 << ec;
2527 messages::internalError(aResp->res);
2528 return;
2529 }
2530 if (subtree.empty())
2531 {
2532 // This is an optional D-Bus object, but user attempted to patch
2533 messages::resourceNotFound(aResp->res, "ComputerSystem",
2534 "IdlePowerSaver");
2535 return;
2536 }
2537 if (subtree.size() > 1)
2538 {
2539 // More then one PowerIdlePowerSaver object is not supported and
2540 // is an error
2541 BMCWEB_LOG_DEBUG
2542 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2543 << subtree.size();
2544 messages::internalError(aResp->res);
2545 return;
2546 }
2547 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2548 {
2549 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2550 messages::internalError(aResp->res);
2551 return;
2552 }
2553 const std::string& path = subtree[0].first;
2554 const std::string& service = subtree[0].second.begin()->first;
2555 if (service.empty())
2556 {
2557 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2558 messages::internalError(aResp->res);
2559 return;
2560 }
Chris Cain37bbf982021-09-20 10:53:09 -05002561
Ed Tanous002d39b2022-05-31 08:59:27 -07002562 // Valid Power IdlePowerSaver object found, now set any values that
2563 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002564
Ed Tanous002d39b2022-05-31 08:59:27 -07002565 if (ipsEnable)
2566 {
2567 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002568 [aResp](const boost::system::error_code ec2) {
2569 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002570 {
Ed Tanous8a592812022-06-04 09:06:59 -07002571 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002572 messages::internalError(aResp->res);
2573 return;
2574 }
2575 },
2576 service, path, "org.freedesktop.DBus.Properties", "Set",
2577 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2578 dbus::utility::DbusVariantType(*ipsEnable));
2579 }
2580 if (ipsEnterUtil)
2581 {
2582 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002583 [aResp](const boost::system::error_code ec2) {
2584 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002585 {
Ed Tanous8a592812022-06-04 09:06:59 -07002586 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002587 messages::internalError(aResp->res);
2588 return;
2589 }
2590 },
2591 service, path, "org.freedesktop.DBus.Properties", "Set",
2592 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2593 "EnterUtilizationPercent",
2594 dbus::utility::DbusVariantType(*ipsEnterUtil));
2595 }
2596 if (ipsEnterTime)
2597 {
2598 // Convert from seconds into milliseconds for DBus
2599 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2600 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002601 [aResp](const boost::system::error_code ec2) {
2602 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002603 {
Ed Tanous8a592812022-06-04 09:06:59 -07002604 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002605 messages::internalError(aResp->res);
2606 return;
2607 }
2608 },
2609 service, path, "org.freedesktop.DBus.Properties", "Set",
2610 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2611 "EnterDwellTime",
2612 dbus::utility::DbusVariantType(timeMilliseconds));
2613 }
2614 if (ipsExitUtil)
2615 {
2616 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002617 [aResp](const boost::system::error_code ec2) {
2618 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002619 {
Ed Tanous8a592812022-06-04 09:06:59 -07002620 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002621 messages::internalError(aResp->res);
2622 return;
2623 }
2624 },
2625 service, path, "org.freedesktop.DBus.Properties", "Set",
2626 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2627 "ExitUtilizationPercent",
2628 dbus::utility::DbusVariantType(*ipsExitUtil));
2629 }
2630 if (ipsExitTime)
2631 {
2632 // Convert from seconds into milliseconds for DBus
2633 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2634 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002635 [aResp](const boost::system::error_code ec2) {
2636 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002637 {
Ed Tanous8a592812022-06-04 09:06:59 -07002638 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002639 messages::internalError(aResp->res);
2640 return;
2641 }
2642 },
2643 service, path, "org.freedesktop.DBus.Properties", "Set",
2644 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2645 "ExitDwellTime",
2646 dbus::utility::DbusVariantType(timeMilliseconds));
2647 }
Chris Cain37bbf982021-09-20 10:53:09 -05002648 },
2649 "xyz.openbmc_project.ObjectMapper",
2650 "/xyz/openbmc_project/object_mapper",
2651 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2652 std::array<const char*, 1>{
2653 "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
2654
2655 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2656}
2657
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002658inline void handleComputerSystemHead(
2659 crow::App& app, const crow::Request& req,
2660 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2661{
2662 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2663 {
2664 return;
2665 }
2666 asyncResp->res.addHeader(
2667 boost::beast::http::field::link,
2668 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2669}
2670
Yong Lic45f0082019-10-10 14:19:01 +08002671/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002672 * SystemsCollection derived class for delivering ComputerSystems Collection
2673 * Schema
2674 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002675inline void requestRoutesSystemsCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002676{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002677 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002678 .privileges(redfish::privileges::headComputerSystemCollection)
2679 .methods(boost::beast::http::verb::head)(
2680 std::bind_front(handleComputerSystemHead, std::ref(app)));
2681
2682 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanoused398212021-06-09 17:05:54 -07002683 .privileges(redfish::privileges::getComputerSystemCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002684 .methods(boost::beast::http::verb::get)(
Ed Tanousf4c99e72021-10-04 17:02:43 -07002685 [&app](const crow::Request& req,
2686 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002687 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002688 {
2689 return;
2690 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002691
2692 asyncResp->res.addHeader(
2693 boost::beast::http::field::link,
2694 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002695 asyncResp->res.jsonValue["@odata.type"] =
2696 "#ComputerSystemCollection.ComputerSystemCollection";
2697 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2698 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002699
Ed Tanous002d39b2022-05-31 08:59:27 -07002700 sdbusplus::asio::getProperty<std::string>(
2701 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2702 "/xyz/openbmc_project/network/hypervisor",
2703 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
Ed Tanous8a592812022-06-04 09:06:59 -07002704 [asyncResp](const boost::system::error_code ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002705 const std::string& /*hostName*/) {
2706 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2707 ifaceArray = nlohmann::json::array();
2708 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Ed Tanous14766872022-03-15 10:44:42 -07002709
Ed Tanous002d39b2022-05-31 08:59:27 -07002710 nlohmann::json::object_t system;
2711 system["@odata.id"] = "/redfish/v1/Systems/system";
2712 ifaceArray.push_back(std::move(system));
2713 count = ifaceArray.size();
Ed Tanous8a592812022-06-04 09:06:59 -07002714 if (!ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002715 {
2716 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2717 nlohmann::json::object_t hypervisor;
2718 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2719 ifaceArray.push_back(std::move(hypervisor));
2720 count = ifaceArray.size();
2721 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002722 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002723 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002724}
Sunitha Harish462023a2020-02-19 08:34:59 -06002725
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002726/**
2727 * Function transceives data with dbus directly.
2728 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002729inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002730{
2731 constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2732 constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2733 constexpr char const* interfaceName =
2734 "xyz.openbmc_project.Control.Host.NMI";
2735 constexpr char const* method = "NMI";
2736
2737 crow::connections::systemBus->async_method_call(
2738 [asyncResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002739 if (ec)
2740 {
2741 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2742 messages::internalError(asyncResp->res);
2743 return;
2744 }
2745 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002746 },
2747 serviceName, objectPath, interfaceName, method);
2748}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002749
2750/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002751 * SystemActionsReset class supports handle POST method for Reset action.
2752 * The class retrieves and sends data directly to D-Bus.
2753 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002754inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002755{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002756 /**
2757 * Function handles POST method request.
2758 * Analyzes POST body message before sends Reset request data to D-Bus.
2759 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002760 BMCWEB_ROUTE(app,
2761 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002762 .privileges(redfish::privileges::postComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002763 .methods(boost::beast::http::verb::post)(
2764 [&app](const crow::Request& req,
2765 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002766 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002767 {
2768 return;
2769 }
2770 std::string resetType;
2771 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
2772 resetType))
2773 {
2774 return;
2775 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002776
Ed Tanous002d39b2022-05-31 08:59:27 -07002777 // Get the command and host vs. chassis
2778 std::string command;
2779 bool hostCommand = true;
2780 if ((resetType == "On") || (resetType == "ForceOn"))
2781 {
2782 command = "xyz.openbmc_project.State.Host.Transition.On";
2783 hostCommand = true;
2784 }
2785 else if (resetType == "ForceOff")
2786 {
2787 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2788 hostCommand = false;
2789 }
2790 else if (resetType == "ForceRestart")
2791 {
2792 command =
2793 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2794 hostCommand = true;
2795 }
2796 else if (resetType == "GracefulShutdown")
2797 {
2798 command = "xyz.openbmc_project.State.Host.Transition.Off";
2799 hostCommand = true;
2800 }
2801 else if (resetType == "GracefulRestart")
2802 {
2803 command =
2804 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2805 hostCommand = true;
2806 }
2807 else if (resetType == "PowerCycle")
2808 {
2809 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2810 hostCommand = true;
2811 }
2812 else if (resetType == "Nmi")
2813 {
2814 doNMI(asyncResp);
2815 return;
2816 }
2817 else
2818 {
2819 messages::actionParameterUnknown(asyncResp->res, "Reset",
2820 resetType);
2821 return;
2822 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002823
Ed Tanous002d39b2022-05-31 08:59:27 -07002824 if (hostCommand)
2825 {
2826 crow::connections::systemBus->async_method_call(
2827 [asyncResp, resetType](const boost::system::error_code ec) {
2828 if (ec)
2829 {
2830 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2831 if (ec.value() == boost::asio::error::invalid_argument)
2832 {
2833 messages::actionParameterNotSupported(
2834 asyncResp->res, resetType, "Reset");
2835 }
2836 else
2837 {
2838 messages::internalError(asyncResp->res);
2839 }
2840 return;
2841 }
2842 messages::success(asyncResp->res);
2843 },
2844 "xyz.openbmc_project.State.Host",
2845 "/xyz/openbmc_project/state/host0",
2846 "org.freedesktop.DBus.Properties", "Set",
2847 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2848 dbus::utility::DbusVariantType{command});
2849 }
2850 else
2851 {
2852 crow::connections::systemBus->async_method_call(
2853 [asyncResp, resetType](const boost::system::error_code ec) {
2854 if (ec)
2855 {
2856 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2857 if (ec.value() == boost::asio::error::invalid_argument)
2858 {
2859 messages::actionParameterNotSupported(
2860 asyncResp->res, resetType, "Reset");
2861 }
2862 else
2863 {
2864 messages::internalError(asyncResp->res);
2865 }
2866 return;
2867 }
2868 messages::success(asyncResp->res);
2869 },
2870 "xyz.openbmc_project.State.Chassis",
2871 "/xyz/openbmc_project/state/chassis0",
2872 "org.freedesktop.DBus.Properties", "Set",
2873 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2874 dbus::utility::DbusVariantType{command});
2875 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002876 });
2877}
Ed Tanouscc340dd2018-08-29 13:43:38 -07002878
Ed Tanous38c8a6f2022-09-01 16:37:27 -07002879inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002880 App& app, const crow::Request& req,
2881 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2882{
2883 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2884 {
2885 return;
2886 }
2887
2888 asyncResp->res.addHeader(
2889 boost::beast::http::field::link,
2890 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2891}
2892
Ed Tanouscc340dd2018-08-29 13:43:38 -07002893/**
Ed Tanous66173382018-08-15 18:20:59 -07002894 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002895 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002896inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002897{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002898
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002899 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2900 .privileges(redfish::privileges::headComputerSystem)
2901 .methods(boost::beast::http::verb::head)(
2902 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002903 /**
2904 * Functions triggers appropriate requests on DBus
2905 */
Ed Tanous22d268c2022-05-19 09:39:07 -07002906 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002907 .privileges(redfish::privileges::getComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002908 .methods(boost::beast::http::verb::get)(
2909 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002910 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2911 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002912 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002913 {
2914 return;
2915 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002916 if (systemName != "system")
2917 {
2918 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2919 systemName);
2920 return;
2921 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002922 asyncResp->res.addHeader(
2923 boost::beast::http::field::link,
2924 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002925 asyncResp->res.jsonValue["@odata.type"] =
2926 "#ComputerSystem.v1_16_0.ComputerSystem";
2927 asyncResp->res.jsonValue["Name"] = "system";
2928 asyncResp->res.jsonValue["Id"] = "system";
2929 asyncResp->res.jsonValue["SystemType"] = "Physical";
2930 asyncResp->res.jsonValue["Description"] = "Computer System";
2931 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
2932 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
2933 "Disabled";
2934 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
2935 uint64_t(0);
2936 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
2937 "Disabled";
2938 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07002939
Ed Tanous002d39b2022-05-31 08:59:27 -07002940 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
2941 "/redfish/v1/Systems/system/Processors";
2942 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
2943 "/redfish/v1/Systems/system/Memory";
2944 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
2945 "/redfish/v1/Systems/system/Storage";
Ed Tanous029573d2019-02-01 10:57:49 -08002946
Ed Tanous002d39b2022-05-31 08:59:27 -07002947 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
2948 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
2949 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
2950 ["@Redfish.ActionInfo"] =
2951 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002952
Ed Tanous002d39b2022-05-31 08:59:27 -07002953 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
2954 "/redfish/v1/Systems/system/LogServices";
2955 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
2956 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08002957
Ed Tanous002d39b2022-05-31 08:59:27 -07002958 nlohmann::json::array_t managedBy;
2959 nlohmann::json& manager = managedBy.emplace_back();
2960 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
2961 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
2962 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
2963 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002964
Ed Tanous002d39b2022-05-31 08:59:27 -07002965 // Fill in SerialConsole info
2966 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
2967 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
2968 true;
Ed Tanous14766872022-03-15 10:44:42 -07002969
Ed Tanous002d39b2022-05-31 08:59:27 -07002970 // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
2971 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
2972 true;
2973 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
2974 asyncResp->res
2975 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
2976 "Press ~. to exit console";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002977
2978#ifdef BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07002979 // Fill in GraphicalConsole info
2980 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
2981 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
2982 4;
Ed Tanous613dabe2022-07-09 11:17:36 -07002983 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
2984 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07002985
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002986#endif // BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07002987 constexpr const std::array<const char*, 4> inventoryForSystems = {
2988 "xyz.openbmc_project.Inventory.Item.Dimm",
2989 "xyz.openbmc_project.Inventory.Item.Cpu",
2990 "xyz.openbmc_project.Inventory.Item.Drive",
2991 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07002992
Ed Tanous002d39b2022-05-31 08:59:27 -07002993 auto health = std::make_shared<HealthPopulate>(asyncResp);
2994 crow::connections::systemBus->async_method_call(
2995 [health](const boost::system::error_code ec,
2996 const std::vector<std::string>& resp) {
2997 if (ec)
2998 {
2999 // no inventory
3000 return;
3001 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003002
Ed Tanous002d39b2022-05-31 08:59:27 -07003003 health->inventory = resp;
3004 },
3005 "xyz.openbmc_project.ObjectMapper",
3006 "/xyz/openbmc_project/object_mapper",
3007 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
3008 int32_t(0), inventoryForSystems);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003009
Ed Tanous002d39b2022-05-31 08:59:27 -07003010 health->populate();
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003011
Ed Tanous002d39b2022-05-31 08:59:27 -07003012 getMainChassisId(asyncResp,
3013 [](const std::string& chassisId,
3014 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3015 nlohmann::json::array_t chassisArray;
3016 nlohmann::json& chassis = chassisArray.emplace_back();
3017 chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId;
3018 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3019 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003020
Ed Tanous002d39b2022-05-31 08:59:27 -07003021 getLocationIndicatorActive(asyncResp);
3022 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3023 getIndicatorLedState(asyncResp);
3024 getComputerSystem(asyncResp, health);
3025 getHostState(asyncResp);
3026 getBootProperties(asyncResp);
3027 getBootProgress(asyncResp);
Hieu Huynhb6d5d452022-10-07 09:41:46 +00003028 getBootProgressLastStateTime(asyncResp);
Ed Tanous002d39b2022-05-31 08:59:27 -07003029 getPCIeDeviceList(asyncResp, "PCIeDevices");
3030 getHostWatchdogTimer(asyncResp);
3031 getPowerRestorePolicy(asyncResp);
3032 getAutomaticRetry(asyncResp);
3033 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003034#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanous002d39b2022-05-31 08:59:27 -07003035 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003036#endif
Ed Tanous002d39b2022-05-31 08:59:27 -07003037 getTrustedModuleRequiredToBoot(asyncResp);
3038 getPowerMode(asyncResp);
3039 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003040 });
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003041
Ed Tanous22d268c2022-05-19 09:39:07 -07003042 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003043 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003044 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003045 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003046 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3047 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003048 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003049 {
3050 return;
3051 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003052 if (systemName != "system")
3053 {
3054 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3055 systemName);
3056 return;
3057 }
3058
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003059 asyncResp->res.addHeader(
3060 boost::beast::http::field::link,
3061 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3062
Ed Tanous002d39b2022-05-31 08:59:27 -07003063 std::optional<bool> locationIndicatorActive;
3064 std::optional<std::string> indicatorLed;
3065 std::optional<std::string> assetTag;
3066 std::optional<std::string> powerRestorePolicy;
3067 std::optional<std::string> powerMode;
3068 std::optional<bool> wdtEnable;
3069 std::optional<std::string> wdtTimeOutAction;
3070 std::optional<std::string> bootSource;
3071 std::optional<std::string> bootType;
3072 std::optional<std::string> bootEnable;
3073 std::optional<std::string> bootAutomaticRetry;
3074 std::optional<bool> bootTrustedModuleRequired;
3075 std::optional<bool> ipsEnable;
3076 std::optional<uint8_t> ipsEnterUtil;
3077 std::optional<uint64_t> ipsEnterTime;
3078 std::optional<uint8_t> ipsExitUtil;
3079 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003080
Ed Tanous002d39b2022-05-31 08:59:27 -07003081 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003082 if (!json_util::readJsonPatch(
3083 req, asyncResp->res,
3084 "IndicatorLED", indicatorLed,
3085 "LocationIndicatorActive", locationIndicatorActive,
3086 "AssetTag", assetTag,
3087 "PowerRestorePolicy", powerRestorePolicy,
3088 "PowerMode", powerMode,
3089 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3090 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3091 "Boot/BootSourceOverrideTarget", bootSource,
3092 "Boot/BootSourceOverrideMode", bootType,
3093 "Boot/BootSourceOverrideEnabled", bootEnable,
3094 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3095 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3096 "IdlePowerSaver/Enabled", ipsEnable,
3097 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3098 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3099 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3100 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3101 {
3102 return;
3103 }
Ed Tanous002d39b2022-05-31 08:59:27 -07003104 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003105
Ed Tanous002d39b2022-05-31 08:59:27 -07003106 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003107
Ed Tanous002d39b2022-05-31 08:59:27 -07003108 if (assetTag)
3109 {
3110 setAssetTag(asyncResp, *assetTag);
3111 }
James Feistb49ac872019-05-21 15:12:01 -07003112
Ed Tanous002d39b2022-05-31 08:59:27 -07003113 if (wdtEnable || wdtTimeOutAction)
3114 {
3115 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3116 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003117
Ed Tanous002d39b2022-05-31 08:59:27 -07003118 if (bootSource || bootType || bootEnable)
3119 {
3120 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3121 }
3122 if (bootAutomaticRetry)
3123 {
3124 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3125 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003126
Ed Tanous002d39b2022-05-31 08:59:27 -07003127 if (bootTrustedModuleRequired)
3128 {
3129 setTrustedModuleRequiredToBoot(asyncResp,
3130 *bootTrustedModuleRequired);
3131 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003132
Ed Tanous002d39b2022-05-31 08:59:27 -07003133 if (locationIndicatorActive)
3134 {
3135 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3136 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003137
Ed Tanous002d39b2022-05-31 08:59:27 -07003138 // TODO (Gunnar): Remove IndicatorLED after enough time has
3139 // passed
3140 if (indicatorLed)
3141 {
3142 setIndicatorLedState(asyncResp, *indicatorLed);
3143 asyncResp->res.addHeader(boost::beast::http::field::warning,
3144 "299 - \"IndicatorLED is deprecated. Use "
3145 "LocationIndicatorActive instead.\"");
3146 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003147
Ed Tanous002d39b2022-05-31 08:59:27 -07003148 if (powerRestorePolicy)
3149 {
3150 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3151 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003152
Ed Tanous002d39b2022-05-31 08:59:27 -07003153 if (powerMode)
3154 {
3155 setPowerMode(asyncResp, *powerMode);
3156 }
Chris Cain37bbf982021-09-20 10:53:09 -05003157
Ed Tanous002d39b2022-05-31 08:59:27 -07003158 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3159 ipsExitTime)
3160 {
3161 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3162 ipsExitUtil, ipsExitTime);
3163 }
3164 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003165}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303166
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003167inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003168 crow::App& app, const crow::Request& req,
3169 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3170{
3171 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3172 {
3173 return;
3174 }
3175 asyncResp->res.addHeader(
3176 boost::beast::http::field::link,
3177 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3178}
3179
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303180/**
3181 * SystemResetActionInfo derived class for delivering Computer Systems
3182 * ResetType AllowableValues using ResetInfo schema.
3183 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003184inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303185{
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003186 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3187 .privileges(redfish::privileges::headActionInfo)
3188 .methods(boost::beast::http::verb::head)(std::bind_front(
3189 handleSystemCollectionResetActionHead, std::ref(app)));
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303190 /**
3191 * Functions triggers appropriate requests on DBus
3192 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003193 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003194 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003195 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003196 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003197 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3198 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003199 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003200 {
3201 return;
3202 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003203 if (systemName != "system")
3204 {
3205 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3206 systemName);
3207 return;
3208 }
3209
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003210 asyncResp->res.addHeader(
3211 boost::beast::http::field::link,
3212 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
Ed Tanous14766872022-03-15 10:44:42 -07003213
Ed Tanous002d39b2022-05-31 08:59:27 -07003214 asyncResp->res.jsonValue["@odata.id"] =
3215 "/redfish/v1/Systems/system/ResetActionInfo";
3216 asyncResp->res.jsonValue["@odata.type"] =
3217 "#ActionInfo.v1_1_2.ActionInfo";
3218 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3219 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
Nan Zhou3215e702022-06-01 16:55:13 +00003220
3221 nlohmann::json::array_t parameters;
3222 nlohmann::json::object_t parameter;
3223
3224 parameter["Name"] = "ResetType";
3225 parameter["Required"] = true;
3226 parameter["DataType"] = "String";
3227 nlohmann::json::array_t allowableValues;
3228 allowableValues.emplace_back("On");
3229 allowableValues.emplace_back("ForceOff");
3230 allowableValues.emplace_back("ForceOn");
3231 allowableValues.emplace_back("ForceRestart");
3232 allowableValues.emplace_back("GracefulRestart");
3233 allowableValues.emplace_back("GracefulShutdown");
3234 allowableValues.emplace_back("PowerCycle");
3235 allowableValues.emplace_back("Nmi");
3236 parameter["AllowableValues"] = std::move(allowableValues);
3237 parameters.emplace_back(std::move(parameter));
3238
3239 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
Ed Tanous002d39b2022-05-31 08:59:27 -07003240 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003241}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003242} // namespace redfish