blob: 864a8d963e5b74264b7ae270a3fb2f87952a5991 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "app.hpp"
Jonathan Doman1e1e5982021-06-11 09:36:17 -070019#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080020#include "dbus_utility.hpp"
James Feistb49ac872019-05-21 15:12:01 -070021#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080022#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080023#include "pcie.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070024#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080025#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080026#include "registries/privilege_registry.hpp"
27#include "utils/dbus_utils.hpp"
28#include "utils/json_utils.hpp"
29#include "utils/sw_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070030#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080031
Ed Tanous9712f8a2018-09-21 13:38:49 -070032#include <boost/container/flat_map.hpp>
George Liue99073f2022-12-09 11:06:16 +080033#include <boost/system/error_code.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070034#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020035#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050036
George Liu7a1dbc42022-12-07 16:03:22 +080037#include <array>
38#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080039#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020040
Ed Tanous1abe55e2018-09-05 08:30:59 -070041namespace redfish
42{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020043
Alpana Kumari9d3ae102019-04-12 06:49:32 -050044/**
45 * @brief Updates the Functional State of DIMMs
46 *
47 * @param[in] aResp Shared pointer for completing asynchronous calls
48 * @param[in] dimmState Dimm's Functional state, true/false
49 *
50 * @return None.
51 */
zhanghch058d1b46d2021-04-01 11:18:24 +080052inline void
53 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070054 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050055{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070056 BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050057
Gunnar Mills4e0453b2020-07-08 14:00:30 -050058 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050059 // Update STATE only if previous State was DISABLED and current Dimm is
60 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070061 const nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050062 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
63 if (prevMemSummary == "Disabled")
64 {
Ed Tanouse05aec52022-01-25 10:28:56 -080065 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050066 {
67 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
68 "Enabled";
69 }
70 }
71}
72
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050073/*
74 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
75 *
76 * @param[in] aResp Shared pointer for completing asynchronous calls
77 * @param[in] cpuPresenceState CPU present or not
78 *
79 * @return None.
80 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -070081inline void
82 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
83 bool isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050084{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070085 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086
Ed Tanous55f79e62022-01-25 11:26:16 -080087 if (isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050088 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080090 aResp->res.jsonValue["ProcessorSummary"]["Count"];
Ed Tanous55f79e62022-01-25 11:26:16 -080091 auto* procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050092 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080093 if (procCountPtr != nullptr)
94 {
95 // shouldn't be possible to be nullptr
96 *procCountPtr += 1;
97 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099}
100
101/*
102 * @brief Update "ProcessorSummary" "Status" "State" based on
103 * CPU Functional State
104 *
105 * @param[in] aResp Shared pointer for completing asynchronous calls
106 * @param[in] cpuFunctionalState is CPU functional true/false
107 *
108 * @return None.
109 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700110inline void
111 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
112 bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500113{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700114 BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500115
Ed Tanous02cad962022-06-30 16:50:15 -0700116 const nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500117 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
118
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500119 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500120 // Update STATE only if previous State was Non_Functional and current CPU is
121 // Functional.
122 if (prevProcState == "Disabled")
123 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800124 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500125 {
126 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
127 "Enabled";
128 }
129 }
130}
131
Ali Ahmed382d6472021-09-03 16:53:53 -0500132inline void getProcessorProperties(
133 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
134 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
135 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500136{
137
138 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
139
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200140 // TODO: Get Model
141
142 const uint16_t* coreCount = nullptr;
143
144 const bool success = sdbusplus::unpackPropertiesNoThrow(
145 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
146
147 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500148 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200149 messages::internalError(aResp->res);
150 return;
151 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500152
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200153 if (coreCount != nullptr)
154 {
155 nlohmann::json& coreCountJson =
156 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
157 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500158
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200159 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500160 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200161 coreCountJson = *coreCount;
162 }
163 else
164 {
165 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500166 }
167 }
168}
169
170/*
171 * @brief Get ProcessorSummary fields
172 *
173 * @param[in] aResp Shared pointer for completing asynchronous calls
174 * @param[in] service dbus service for Cpu Information
175 * @param[in] path dbus path for Cpu
176 *
177 * @return None.
178 */
179inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
180 const std::string& service,
181 const std::string& path)
182{
183
Ali Ahmed382d6472021-09-03 16:53:53 -0500184 auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
185 const bool cpuPresenceCheck) {
186 if (ec3)
187 {
188 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
189 return;
190 }
191 modifyCpuPresenceState(aResp, cpuPresenceCheck);
192 };
193
194 auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
195 const bool cpuFunctionalCheck) {
196 if (ec3)
197 {
198 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
199 return;
200 }
201 modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
202 };
203
204 // Get the Presence of CPU
205 sdbusplus::asio::getProperty<bool>(
206 *crow::connections::systemBus, service, path,
207 "xyz.openbmc_project.Inventory.Item", "Present",
208 std::move(getCpuPresenceState));
209
210 // Get the Functional State
211 sdbusplus::asio::getProperty<bool>(
212 *crow::connections::systemBus, service, path,
213 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
214 std::move(getCpuFunctionalState));
215
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200216 sdbusplus::asio::getAllProperties(
217 *crow::connections::systemBus, service, path,
218 "xyz.openbmc_project.Inventory.Item.Cpu",
Ali Ahmed03fbed92021-09-03 02:33:43 -0500219 [aResp, service,
220 path](const boost::system::error_code ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800221 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700222 if (ec2)
223 {
224 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
225 messages::internalError(aResp->res);
226 return;
227 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500228 getProcessorProperties(aResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200229 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500230}
231
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500232/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700233 * @brief Retrieves computer system properties over dbus
234 *
235 * @param[in] aResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500236 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700237 *
238 * @return None.
239 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700240inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800241 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700242 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700243{
Ed Tanous6c34de42018-08-29 13:37:36 -0700244 BMCWEB_LOG_DEBUG << "Get available system components.";
George Liue99073f2022-12-09 11:06:16 +0800245 constexpr std::array<std::string_view, 5> interfaces = {
246 "xyz.openbmc_project.Inventory.Decorator.Asset",
247 "xyz.openbmc_project.Inventory.Item.Cpu",
248 "xyz.openbmc_project.Inventory.Item.Dimm",
249 "xyz.openbmc_project.Inventory.Item.System",
250 "xyz.openbmc_project.Common.UUID",
251 };
252 dbus::utility::getSubTree(
253 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800254 [aResp,
George Liue99073f2022-12-09 11:06:16 +0800255 systemHealth](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800256 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700257 if (ec)
258 {
259 BMCWEB_LOG_DEBUG << "DBUS response error";
260 messages::internalError(aResp->res);
261 return;
262 }
263 // Iterate over all retrieved ObjectPaths.
264 for (const std::pair<
265 std::string,
266 std::vector<std::pair<std::string, std::vector<std::string>>>>&
267 object : subtree)
268 {
269 const std::string& path = object.first;
270 BMCWEB_LOG_DEBUG << "Got path: " << path;
271 const std::vector<std::pair<std::string, std::vector<std::string>>>&
272 connectionNames = object.second;
273 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700274 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700275 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700276 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700277
278 auto memoryHealth = std::make_shared<HealthPopulate>(
279 aResp, "/MemorySummary/Status"_json_pointer);
280
281 auto cpuHealth = std::make_shared<HealthPopulate>(
282 aResp, "/ProcessorSummary/Status"_json_pointer);
283
284 systemHealth->children.emplace_back(memoryHealth);
285 systemHealth->children.emplace_back(cpuHealth);
286
287 // This is not system, so check if it's cpu, dimm, UUID or
288 // BiosVer
289 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700290 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700291 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700292 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700293 if (interfaceName ==
294 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700295 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700296 BMCWEB_LOG_DEBUG
297 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500298
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200299 sdbusplus::asio::getAllProperties(
300 *crow::connections::systemBus, connection.first,
301 path, "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanous002d39b2022-05-31 08:59:27 -0700302 [aResp, service{connection.first},
303 path](const boost::system::error_code ec2,
304 const dbus::utility::DBusPropertiesMap&
305 properties) {
306 if (ec2)
307 {
308 BMCWEB_LOG_ERROR << "DBUS response error "
309 << ec2;
310 messages::internalError(aResp->res);
311 return;
312 }
313 BMCWEB_LOG_DEBUG << "Got " << properties.size()
314 << " Dimm properties.";
315
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200316 if (properties.empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700317 {
318 sdbusplus::asio::getProperty<bool>(
319 *crow::connections::systemBus, service,
320 path,
321 "xyz.openbmc_project.State."
322 "Decorator.OperationalStatus",
323 "Functional",
324 [aResp](const boost::system::error_code ec3,
325 bool dimmState) {
326 if (ec3)
327 {
328 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000329 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800330 return;
331 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700332 updateDimmProperties(aResp, dimmState);
333 });
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200334 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700335 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200336
337 const uint32_t* memorySizeInKB = nullptr;
338
339 const bool success =
340 sdbusplus::unpackPropertiesNoThrow(
341 dbus_utils::UnpackErrorPrinter(),
342 properties, "MemorySizeInKB",
343 memorySizeInKB);
344
345 if (!success)
346 {
347 messages::internalError(aResp->res);
348 return;
349 }
350
351 if (memorySizeInKB != nullptr)
352 {
353 nlohmann::json& totalMemory =
354 aResp->res
355 .jsonValue["MemorySummary"]
356 ["TotalSystemMemoryGiB"];
357 const uint64_t* preValue =
358 totalMemory.get_ptr<const uint64_t*>();
359 if (preValue == nullptr)
360 {
361 aResp->res
362 .jsonValue["MemorySummary"]
363 ["TotalSystemMemoryGiB"] =
364 *memorySizeInKB / (1024 * 1024);
365 }
366 else
367 {
368 aResp->res
369 .jsonValue["MemorySummary"]
370 ["TotalSystemMemoryGiB"] =
371 *memorySizeInKB / (1024 * 1024) +
372 *preValue;
373 }
374 aResp->res.jsonValue["MemorySummary"]["Status"]
375 ["State"] = "Enabled";
376 }
377 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700378
379 memoryHealth->inventory.emplace_back(path);
380 }
381 else if (interfaceName ==
382 "xyz.openbmc_project.Inventory.Item.Cpu")
383 {
384 BMCWEB_LOG_DEBUG
385 << "Found Cpu, now get its properties.";
386
387 getProcessorSummary(aResp, connection.first, path);
388
389 cpuHealth->inventory.emplace_back(path);
390 }
391 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
392 {
393 BMCWEB_LOG_DEBUG
394 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200395
396 sdbusplus::asio::getAllProperties(
397 *crow::connections::systemBus, connection.first,
398 path, "xyz.openbmc_project.Common.UUID",
Ed Tanous002d39b2022-05-31 08:59:27 -0700399 [aResp](const boost::system::error_code ec3,
400 const dbus::utility::DBusPropertiesMap&
401 properties) {
402 if (ec3)
403 {
404 BMCWEB_LOG_DEBUG << "DBUS response error "
405 << ec3;
406 messages::internalError(aResp->res);
407 return;
408 }
409 BMCWEB_LOG_DEBUG << "Got " << properties.size()
410 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700411
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200412 const std::string* uUID = nullptr;
413
414 const bool success =
415 sdbusplus::unpackPropertiesNoThrow(
416 dbus_utils::UnpackErrorPrinter(),
417 properties, "UUID", uUID);
418
419 if (!success)
420 {
421 messages::internalError(aResp->res);
422 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700423 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200424
425 if (uUID != nullptr)
426 {
427 std::string valueStr = *uUID;
428 if (valueStr.size() == 32)
429 {
430 valueStr.insert(8, 1, '-');
431 valueStr.insert(13, 1, '-');
432 valueStr.insert(18, 1, '-');
433 valueStr.insert(23, 1, '-');
434 }
435 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
436 aResp->res.jsonValue["UUID"] = valueStr;
437 }
438 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700439 }
440 else if (interfaceName ==
441 "xyz.openbmc_project.Inventory.Item.System")
442 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200443 sdbusplus::asio::getAllProperties(
444 *crow::connections::systemBus, connection.first,
445 path,
446 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanous002d39b2022-05-31 08:59:27 -0700447 [aResp](const boost::system::error_code ec2,
448 const dbus::utility::DBusPropertiesMap&
449 propertiesList) {
450 if (ec2)
451 {
452 // doesn't have to include this
453 // interface
454 return;
455 }
456 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
457 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200458
459 const std::string* partNumber = nullptr;
460 const std::string* serialNumber = nullptr;
461 const std::string* manufacturer = nullptr;
462 const std::string* model = nullptr;
463 const std::string* subModel = nullptr;
464
465 const bool success =
466 sdbusplus::unpackPropertiesNoThrow(
467 dbus_utils::UnpackErrorPrinter(),
468 propertiesList, "PartNumber", partNumber,
469 "SerialNumber", serialNumber,
470 "Manufacturer", manufacturer, "Model",
471 model, "SubModel", subModel);
472
473 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700474 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200475 messages::internalError(aResp->res);
476 return;
477 }
478
479 if (partNumber != nullptr)
480 {
481 aResp->res.jsonValue["PartNumber"] =
482 *partNumber;
483 }
484
485 if (serialNumber != nullptr)
486 {
487 aResp->res.jsonValue["SerialNumber"] =
488 *serialNumber;
489 }
490
491 if (manufacturer != nullptr)
492 {
493 aResp->res.jsonValue["Manufacturer"] =
494 *manufacturer;
495 }
496
497 if (model != nullptr)
498 {
499 aResp->res.jsonValue["Model"] = *model;
500 }
501
502 if (subModel != nullptr)
503 {
504 aResp->res.jsonValue["SubModel"] = *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700505 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500506
Ed Tanous002d39b2022-05-31 08:59:27 -0700507 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700508 sw_util::populateSoftwareInformation(
509 aResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700510 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200511 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700512
Ed Tanous002d39b2022-05-31 08:59:27 -0700513 sdbusplus::asio::getProperty<std::string>(
514 *crow::connections::systemBus, connection.first,
515 path,
516 "xyz.openbmc_project.Inventory.Decorator."
517 "AssetTag",
518 "AssetTag",
519 [aResp](const boost::system::error_code ec2,
520 const std::string& value) {
521 if (ec2)
522 {
523 // doesn't have to include this
524 // interface
525 return;
526 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700527
Ed Tanous002d39b2022-05-31 08:59:27 -0700528 aResp->res.jsonValue["AssetTag"] = value;
529 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700530 }
531 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200532 break;
Ed Tanous6c34de42018-08-29 13:37:36 -0700533 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700534 }
Ed Tanous66173382018-08-15 18:20:59 -0700535 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700536}
537
538/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700539 * @brief Retrieves host state properties over dbus
540 *
541 * @param[in] aResp Shared pointer for completing asynchronous calls.
542 *
543 * @return None.
544 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800545inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700546{
547 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700548 sdbusplus::asio::getProperty<std::string>(
549 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
550 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
551 "CurrentHostState",
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800552 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700553 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700554 if (ec)
555 {
556 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700557 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700558 // Service not available, no error, just don't return
559 // host state info
560 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700561 return;
562 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700563 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
564 messages::internalError(aResp->res);
565 return;
566 }
Ed Tanous66173382018-08-15 18:20:59 -0700567
Ed Tanous002d39b2022-05-31 08:59:27 -0700568 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
569 // Verify Host State
570 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
571 {
572 aResp->res.jsonValue["PowerState"] = "On";
573 aResp->res.jsonValue["Status"]["State"] = "Enabled";
574 }
575 else if (hostState ==
576 "xyz.openbmc_project.State.Host.HostState.Quiesced")
577 {
578 aResp->res.jsonValue["PowerState"] = "On";
579 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
580 }
581 else if (hostState ==
582 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
583 {
584 aResp->res.jsonValue["PowerState"] = "On";
585 aResp->res.jsonValue["Status"]["State"] = "InTest";
586 }
587 else if (
588 hostState ==
589 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
590 {
591 aResp->res.jsonValue["PowerState"] = "PoweringOn";
592 aResp->res.jsonValue["Status"]["State"] = "Starting";
593 }
594 else if (hostState ==
595 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
596 {
597 aResp->res.jsonValue["PowerState"] = "PoweringOff";
598 aResp->res.jsonValue["Status"]["State"] = "Disabled";
599 }
600 else
601 {
602 aResp->res.jsonValue["PowerState"] = "Off";
603 aResp->res.jsonValue["Status"]["State"] = "Disabled";
604 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700605 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700606}
607
608/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500609 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530610 *
611 * @param[in] dbusSource The boot source in DBUS speak.
612 *
613 * @return Returns as a string, the boot source in Redfish terms. If translation
614 * cannot be done, returns an empty string.
615 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000616inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530617{
618 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
619 {
620 return "None";
621 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700622 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530623 {
624 return "Hdd";
625 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700626 if (dbusSource ==
627 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530628 {
629 return "Cd";
630 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700631 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530632 {
633 return "Pxe";
634 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700635 if (dbusSource ==
636 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700637 {
638 return "Usb";
639 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700640 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530641}
642
643/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300644 * @brief Translates boot type DBUS property value to redfish.
645 *
646 * @param[in] dbusType The boot type in DBUS speak.
647 *
648 * @return Returns as a string, the boot type in Redfish terms. If translation
649 * cannot be done, returns an empty string.
650 */
651inline std::string dbusToRfBootType(const std::string& dbusType)
652{
653 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
654 {
655 return "Legacy";
656 }
657 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
658 {
659 return "UEFI";
660 }
661 return "";
662}
663
664/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500665 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530666 *
667 * @param[in] dbusMode The boot mode in DBUS speak.
668 *
669 * @return Returns as a string, the boot mode in Redfish terms. If translation
670 * cannot be done, returns an empty string.
671 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000672inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530673{
674 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
675 {
676 return "None";
677 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700678 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530679 {
680 return "Diags";
681 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700682 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530683 {
684 return "BiosSetup";
685 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700686 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530687}
688
689/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600690 * @brief Translates boot progress DBUS property value to redfish.
691 *
692 * @param[in] dbusBootProgress The boot progress in DBUS speak.
693 *
694 * @return Returns as a string, the boot progress in Redfish terms. If
695 * translation cannot be done, returns "None".
696 */
697inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
698{
699 // Now convert the D-Bus BootProgress to the appropriate Redfish
700 // enum
701 std::string rfBpLastState = "None";
702 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
703 "ProgressStages.Unspecified")
704 {
705 rfBpLastState = "None";
706 }
707 else if (dbusBootProgress ==
708 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
709 "PrimaryProcInit")
710 {
711 rfBpLastState = "PrimaryProcessorInitializationStarted";
712 }
713 else if (dbusBootProgress ==
714 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
715 "BusInit")
716 {
717 rfBpLastState = "BusInitializationStarted";
718 }
719 else if (dbusBootProgress ==
720 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
721 "MemoryInit")
722 {
723 rfBpLastState = "MemoryInitializationStarted";
724 }
725 else if (dbusBootProgress ==
726 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
727 "SecondaryProcInit")
728 {
729 rfBpLastState = "SecondaryProcessorInitializationStarted";
730 }
731 else if (dbusBootProgress ==
732 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
733 "PCIInit")
734 {
735 rfBpLastState = "PCIResourceConfigStarted";
736 }
737 else if (dbusBootProgress ==
738 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
739 "SystemSetup")
740 {
741 rfBpLastState = "SetupEntered";
742 }
743 else if (dbusBootProgress ==
744 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
745 "SystemInitComplete")
746 {
747 rfBpLastState = "SystemHardwareInitializationComplete";
748 }
749 else if (dbusBootProgress ==
750 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
751 "OSStart")
752 {
753 rfBpLastState = "OSBootStarted";
754 }
755 else if (dbusBootProgress ==
756 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
757 "OSRunning")
758 {
759 rfBpLastState = "OSRunning";
760 }
761 else
762 {
763 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
764 << dbusBootProgress;
765 // Just return the default
766 }
767 return rfBpLastState;
768}
769
770/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500771 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530772 *
773 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700774 * @param[out] bootSource The DBus source
775 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530776 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700777 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530778 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800779inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500780 const std::string& rfSource,
781 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530782{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300783 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
784 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700785
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530786 if (rfSource == "None")
787 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700788 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530789 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700790 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530791 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700792 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
793 }
794 else if (rfSource == "Hdd")
795 {
796 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
797 }
798 else if (rfSource == "Diags")
799 {
800 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
801 }
802 else if (rfSource == "Cd")
803 {
804 bootSource =
805 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
806 }
807 else if (rfSource == "BiosSetup")
808 {
809 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530810 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700811 else if (rfSource == "Usb")
812 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700813 bootSource =
814 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700815 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530816 else
817 {
George Liu0fda0f12021-11-16 10:06:17 +0800818 BMCWEB_LOG_DEBUG
819 << "Invalid property value for BootSourceOverrideTarget: "
820 << bootSource;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700821 messages::propertyValueNotInList(aResp->res, rfSource,
822 "BootSourceTargetOverride");
823 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530824 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700825 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530826}
Ali Ahmed19817712021-06-29 17:01:52 -0500827
Andrew Geissler978b8802020-11-19 13:36:40 -0600828/**
829 * @brief Retrieves boot progress of the system
830 *
831 * @param[in] aResp Shared pointer for generating response message.
832 *
833 * @return None.
834 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800835inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600836{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700837 sdbusplus::asio::getProperty<std::string>(
838 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
839 "/xyz/openbmc_project/state/host0",
840 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Andrew Geissler978b8802020-11-19 13:36:40 -0600841 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700842 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700843 if (ec)
844 {
845 // BootProgress is an optional object so just do nothing if
846 // not found
847 return;
848 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600849
Ed Tanous002d39b2022-05-31 08:59:27 -0700850 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600851
Ed Tanous002d39b2022-05-31 08:59:27 -0700852 aResp->res.jsonValue["BootProgress"]["LastState"] =
853 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700854 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600855}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530856
857/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000858 * @brief Retrieves boot progress Last Update of the system
859 *
860 * @param[in] aResp Shared pointer for generating response message.
861 *
862 * @return None.
863 */
864inline void getBootProgressLastStateTime(
865 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
866{
867 sdbusplus::asio::getProperty<uint64_t>(
868 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
869 "/xyz/openbmc_project/state/host0",
870 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
871 [aResp](const boost::system::error_code ec,
872 const uint64_t lastStateTime) {
873 if (ec)
874 {
875 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
876 return;
877 }
878
879 // BootProgressLastUpdate is the last time the BootProgress property
880 // was updated. The time is the Epoch time, number of microseconds
881 // since 1 Jan 1970 00::00::00 UTC."
882 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
883 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
884
885 // Convert to ISO 8601 standard
886 aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
887 redfish::time_utils::getDateTimeUintUs(lastStateTime);
888 });
889}
890
891/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300892 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300893 *
894 * @param[in] aResp Shared pointer for generating response message.
895 *
896 * @return None.
897 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300898
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300899inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300900{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700901 sdbusplus::asio::getProperty<std::string>(
902 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
903 "/xyz/openbmc_project/control/host0/boot",
904 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300905 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700906 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700907 if (ec)
908 {
909 // not an error, don't have to have the interface
910 return;
911 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300912
Ed Tanous002d39b2022-05-31 08:59:27 -0700913 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300914
Ed Tanous002d39b2022-05-31 08:59:27 -0700915 aResp->res.jsonValue["Boot"]
916 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700917 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300918
Ed Tanous002d39b2022-05-31 08:59:27 -0700919 auto rfType = dbusToRfBootType(bootType);
920 if (rfType.empty())
921 {
922 messages::internalError(aResp->res);
923 return;
924 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300925
Ed Tanous002d39b2022-05-31 08:59:27 -0700926 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700927 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300928}
929
930/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300931 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530932 *
933 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530934 *
935 * @return None.
936 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300937
938inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530939{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700940 sdbusplus::asio::getProperty<std::string>(
941 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
942 "/xyz/openbmc_project/control/host0/boot",
943 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300944 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700945 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700946 if (ec)
947 {
948 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
949 messages::internalError(aResp->res);
950 return;
951 }
952
953 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
954
955 aResp->res
956 .jsonValue["Boot"]
957 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
958 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
959
960 if (bootModeStr !=
961 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
962 {
963 auto rfMode = dbusToRfBootMode(bootModeStr);
964 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530965 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700966 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
967 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530968 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700969 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700970 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530971}
972
973/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300974 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530975 *
976 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530977 *
978 * @return None.
979 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300980
981inline void
982 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530983{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700984 sdbusplus::asio::getProperty<std::string>(
985 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
986 "/xyz/openbmc_project/control/host0/boot",
987 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300988 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700989 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700990 if (ec)
991 {
992 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +0000993 if (ec.value() == boost::asio::error::host_unreachable)
994 {
995 return;
996 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700997 messages::internalError(aResp->res);
998 return;
999 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301000
Ed Tanous002d39b2022-05-31 08:59:27 -07001001 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301002
Ed Tanous002d39b2022-05-31 08:59:27 -07001003 auto rfSource = dbusToRfBootSource(bootSourceStr);
1004 if (!rfSource.empty())
1005 {
1006 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1007 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001008
Ed Tanous002d39b2022-05-31 08:59:27 -07001009 // Get BootMode as BootSourceOverrideTarget is constructed
1010 // from both BootSource and BootMode
1011 getBootOverrideMode(aResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001012 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301013}
1014
1015/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001016 * @brief This functions abstracts all the logic behind getting a
1017 * "BootSourceOverrideEnabled" property from an overall boot override enable
1018 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301019 *
1020 * @param[in] aResp Shared pointer for generating response message.
1021 *
1022 * @return None.
1023 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001025inline void
1026 processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1027 const bool bootOverrideEnableSetting)
1028{
1029 if (!bootOverrideEnableSetting)
1030 {
1031 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1032 return;
1033 }
1034
1035 // If boot source override is enabled, we need to check 'one_time'
1036 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001037 sdbusplus::asio::getProperty<bool>(
1038 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1039 "/xyz/openbmc_project/control/host0/boot/one_time",
1040 "xyz.openbmc_project.Object.Enable", "Enabled",
1041 [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001042 if (ec)
1043 {
1044 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1045 messages::internalError(aResp->res);
1046 return;
1047 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301048
Ed Tanous002d39b2022-05-31 08:59:27 -07001049 if (oneTimeSetting)
1050 {
1051 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1052 }
1053 else
1054 {
1055 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1056 "Continuous";
1057 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001058 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301059}
1060
1061/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001062 * @brief Retrieves boot override enable over DBUS
1063 *
1064 * @param[in] aResp Shared pointer for generating response message.
1065 *
1066 * @return None.
1067 */
1068
1069inline void
1070 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1071{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001072 sdbusplus::asio::getProperty<bool>(
1073 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1074 "/xyz/openbmc_project/control/host0/boot",
1075 "xyz.openbmc_project.Object.Enable", "Enabled",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001076 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001077 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001078 if (ec)
1079 {
1080 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001081 if (ec.value() == boost::asio::error::host_unreachable)
1082 {
1083 return;
1084 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001085 messages::internalError(aResp->res);
1086 return;
1087 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001088
Ed Tanous002d39b2022-05-31 08:59:27 -07001089 processBootOverrideEnable(aResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001090 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001091}
1092
1093/**
1094 * @brief Retrieves boot source override properties
1095 *
1096 * @param[in] aResp Shared pointer for generating response message.
1097 *
1098 * @return None.
1099 */
1100inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1101{
1102 BMCWEB_LOG_DEBUG << "Get boot information.";
1103
1104 getBootOverrideSource(aResp);
1105 getBootOverrideType(aResp);
1106 getBootOverrideEnable(aResp);
1107}
1108
1109/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001110 * @brief Retrieves the Last Reset Time
1111 *
1112 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1113 * and power off. Even though this is the "system" Redfish object look at the
1114 * chassis D-Bus interface for the LastStateChangeTime since this has the
1115 * last power operation time.
1116 *
1117 * @param[in] aResp Shared pointer for generating response message.
1118 *
1119 * @return None.
1120 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001121inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001122{
1123 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1124
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001125 sdbusplus::asio::getProperty<uint64_t>(
1126 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1127 "/xyz/openbmc_project/state/chassis0",
1128 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1129 [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001130 if (ec)
1131 {
1132 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1133 return;
1134 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001135
Ed Tanous002d39b2022-05-31 08:59:27 -07001136 // LastStateChangeTime is epoch time, in milliseconds
1137 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1138 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001139
Ed Tanous002d39b2022-05-31 08:59:27 -07001140 // Convert to ISO 8601 standard
1141 aResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001142 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001143 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001144}
1145
1146/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001147 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1148 *
1149 * @param[in] aResp Shared pointer for generating response message.
1150 *
1151 * @return None.
1152 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001153inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001154{
1155 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1156
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001157 sdbusplus::asio::getProperty<bool>(
1158 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1159 "/xyz/openbmc_project/control/host0/auto_reboot",
1160 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1161 [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001162 if (ec)
1163 {
1164 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1165 return;
1166 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001167
Ed Tanous002d39b2022-05-31 08:59:27 -07001168 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1169 if (autoRebootEnabled)
1170 {
1171 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1172 "RetryAttempts";
1173 // If AutomaticRetry (AutoReboot) is enabled see how many
1174 // attempts are left
1175 sdbusplus::asio::getProperty<uint32_t>(
1176 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1177 "/xyz/openbmc_project/state/host0",
1178 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1179 "AttemptsLeft",
1180 [aResp](const boost::system::error_code ec2,
1181 const uint32_t autoRebootAttemptsLeft) {
1182 if (ec2)
1183 {
1184 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
1185 return;
1186 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001187
Ed Tanous002d39b2022-05-31 08:59:27 -07001188 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1189 << autoRebootAttemptsLeft;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001190
Ed Tanous002d39b2022-05-31 08:59:27 -07001191 aResp->res
1192 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1193 autoRebootAttemptsLeft;
1194 });
1195 }
1196 else
1197 {
1198 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
1199 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001200
Ed Tanous002d39b2022-05-31 08:59:27 -07001201 // Not on D-Bus. Hardcoded here:
1202 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1203 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001204
Ed Tanous002d39b2022-05-31 08:59:27 -07001205 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1206 // and RetryAttempts. OpenBMC only supports Disabled and
1207 // RetryAttempts.
1208 aResp->res.jsonValue["Boot"]
1209 ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
1210 "Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001211 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001212}
1213
1214/**
George Liuc6a620f2020-04-10 17:18:11 +08001215 * @brief Retrieves power restore policy over DBUS.
1216 *
1217 * @param[in] aResp Shared pointer for generating response message.
1218 *
1219 * @return None.
1220 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001221inline void
1222 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001223{
1224 BMCWEB_LOG_DEBUG << "Get power restore policy";
1225
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001226 sdbusplus::asio::getProperty<std::string>(
1227 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1228 "/xyz/openbmc_project/control/host0/power_restore_policy",
1229 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1230 [aResp](const boost::system::error_code ec, const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001231 if (ec)
1232 {
1233 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1234 return;
1235 }
George Liuc6a620f2020-04-10 17:18:11 +08001236
Ed Tanous002d39b2022-05-31 08:59:27 -07001237 const boost::container::flat_map<std::string, std::string> policyMaps = {
1238 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1239 "AlwaysOn"},
1240 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1241 "AlwaysOff"},
1242 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1243 "LastState"},
1244 // Return `AlwaysOff` when power restore policy set to "None"
1245 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
1246 "AlwaysOff"}};
George Liuc6a620f2020-04-10 17:18:11 +08001247
Ed Tanous002d39b2022-05-31 08:59:27 -07001248 auto policyMapsIt = policyMaps.find(policy);
1249 if (policyMapsIt == policyMaps.end())
1250 {
1251 messages::internalError(aResp->res);
1252 return;
1253 }
George Liuc6a620f2020-04-10 17:18:11 +08001254
Ed Tanous002d39b2022-05-31 08:59:27 -07001255 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001256 });
George Liuc6a620f2020-04-10 17:18:11 +08001257}
1258
1259/**
Ali Ahmed19817712021-06-29 17:01:52 -05001260 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1261 * TPM is required for booting the host.
1262 *
1263 * @param[in] aResp Shared pointer for generating response message.
1264 *
1265 * @return None.
1266 */
1267inline void getTrustedModuleRequiredToBoot(
1268 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1269{
1270 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
George Liue99073f2022-12-09 11:06:16 +08001271 constexpr std::array<std::string_view, 1> interfaces = {
1272 "xyz.openbmc_project.Control.TPM.Policy"};
1273 dbus::utility::getSubTree(
1274 "/", 0, interfaces,
1275 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001276 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001277 if (ec)
1278 {
1279 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1280 << ec;
1281 // This is an optional D-Bus object so just return if
1282 // error occurs
1283 return;
1284 }
1285 if (subtree.empty())
1286 {
1287 // As noted above, this is an optional interface so just return
1288 // if there is no instance found
1289 return;
1290 }
1291
1292 /* When there is more than one TPMEnable object... */
1293 if (subtree.size() > 1)
1294 {
1295 BMCWEB_LOG_DEBUG
1296 << "DBUS response has more than 1 TPM Enable object:"
1297 << subtree.size();
1298 // Throw an internal Error and return
1299 messages::internalError(aResp->res);
1300 return;
1301 }
1302
1303 // Make sure the Dbus response map has a service and objectPath
1304 // field
1305 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1306 {
1307 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1308 messages::internalError(aResp->res);
1309 return;
1310 }
1311
1312 const std::string& path = subtree[0].first;
1313 const std::string& serv = subtree[0].second.begin()->first;
1314
1315 // Valid TPM Enable object found, now reading the current value
1316 sdbusplus::asio::getProperty<bool>(
1317 *crow::connections::systemBus, serv, path,
1318 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanous8a592812022-06-04 09:06:59 -07001319 [aResp](const boost::system::error_code ec2, bool tpmRequired) {
1320 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001321 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001322 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001323 << ec2;
Ali Ahmed19817712021-06-29 17:01:52 -05001324 messages::internalError(aResp->res);
1325 return;
1326 }
1327
Ed Tanous002d39b2022-05-31 08:59:27 -07001328 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001329 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001330 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1331 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001332 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001333 else
1334 {
1335 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1336 "Disabled";
1337 }
1338 });
George Liue99073f2022-12-09 11:06:16 +08001339 });
Ali Ahmed19817712021-06-29 17:01:52 -05001340}
1341
1342/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001343 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1344 * TPM is required for booting the host.
1345 *
1346 * @param[in] aResp Shared pointer for generating response message.
1347 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1348 *
1349 * @return None.
1350 */
1351inline void setTrustedModuleRequiredToBoot(
1352 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
1353{
1354 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
George Liue99073f2022-12-09 11:06:16 +08001355 constexpr std::array<std::string_view, 1> interfaces = {
1356 "xyz.openbmc_project.Control.TPM.Policy"};
1357 dbus::utility::getSubTree(
1358 "/", 0, interfaces,
1359 [aResp,
1360 tpmRequired](const boost::system::error_code& ec,
1361 const 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));
George Liue99073f2022-12-09 11:06:16 +08001422 });
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001423}
1424
1425/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301426 * @brief Sets boot properties into DBUS object(s).
1427 *
1428 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001429 * @param[in] bootType The boot type to set.
1430 * @return Integer error code.
1431 */
1432inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001433 const std::optional<std::string>& bootType)
1434{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001435 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001436
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001437 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001438 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001439 return;
1440 }
1441
1442 // Source target specified
1443 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1444 // Figure out which DBUS interface and property to use
1445 if (*bootType == "Legacy")
1446 {
1447 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1448 }
1449 else if (*bootType == "UEFI")
1450 {
1451 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1452 }
1453 else
1454 {
1455 BMCWEB_LOG_DEBUG << "Invalid property value for "
1456 "BootSourceOverrideMode: "
1457 << *bootType;
1458 messages::propertyValueNotInList(aResp->res, *bootType,
1459 "BootSourceOverrideMode");
1460 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001461 }
1462
1463 // Act on validated parameters
1464 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1465
1466 crow::connections::systemBus->async_method_call(
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001467 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001468 if (ec)
1469 {
1470 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1471 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001472 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001473 messages::resourceNotFound(aResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001474 return;
1475 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001476 messages::internalError(aResp->res);
1477 return;
1478 }
1479 BMCWEB_LOG_DEBUG << "Boot type update done.";
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001480 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001481 "xyz.openbmc_project.Settings",
1482 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001483 "org.freedesktop.DBus.Properties", "Set",
1484 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001485 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001486}
1487
1488/**
1489 * @brief Sets boot properties into DBUS object(s).
1490 *
1491 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001492 * @param[in] bootType The boot type to set.
1493 * @return Integer error code.
1494 */
1495inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1496 const std::optional<std::string>& bootEnable)
1497{
1498 if (!bootEnable)
1499 {
1500 return;
1501 }
1502 // Source target specified
1503 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1504
1505 bool bootOverrideEnable = false;
1506 bool bootOverridePersistent = false;
1507 // Figure out which DBUS interface and property to use
1508 if (*bootEnable == "Disabled")
1509 {
1510 bootOverrideEnable = false;
1511 }
1512 else if (*bootEnable == "Once")
1513 {
1514 bootOverrideEnable = true;
1515 bootOverridePersistent = false;
1516 }
1517 else if (*bootEnable == "Continuous")
1518 {
1519 bootOverrideEnable = true;
1520 bootOverridePersistent = true;
1521 }
1522 else
1523 {
George Liu0fda0f12021-11-16 10:06:17 +08001524 BMCWEB_LOG_DEBUG
1525 << "Invalid property value for BootSourceOverrideEnabled: "
1526 << *bootEnable;
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001527 messages::propertyValueNotInList(aResp->res, *bootEnable,
1528 "BootSourceOverrideEnabled");
1529 return;
1530 }
1531
1532 // Act on validated parameters
1533 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1534
1535 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07001536 [aResp](const boost::system::error_code ec2) {
1537 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001538 {
Ed Tanous8a592812022-06-04 09:06:59 -07001539 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07001540 messages::internalError(aResp->res);
1541 return;
1542 }
1543 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001544 },
1545 "xyz.openbmc_project.Settings",
1546 "/xyz/openbmc_project/control/host0/boot",
1547 "org.freedesktop.DBus.Properties", "Set",
1548 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001549 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001550
1551 if (!bootOverrideEnable)
1552 {
1553 return;
1554 }
1555
1556 // In case boot override is enabled we need to set correct value for the
1557 // 'one_time' enable DBus interface
1558 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1559 << bootOverridePersistent;
1560
1561 crow::connections::systemBus->async_method_call(
1562 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001563 if (ec)
1564 {
1565 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1566 messages::internalError(aResp->res);
1567 return;
1568 }
1569 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001570 },
1571 "xyz.openbmc_project.Settings",
1572 "/xyz/openbmc_project/control/host0/boot/one_time",
1573 "org.freedesktop.DBus.Properties", "Set",
1574 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001575 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001576}
1577
1578/**
1579 * @brief Sets boot properties into DBUS object(s).
1580 *
1581 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301582 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301583 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001584 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301585 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001586inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001587 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301588{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001589 std::string bootSourceStr;
1590 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001591
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001592 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301593 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001594 return;
1595 }
1596
1597 // Source target specified
1598 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1599 // Figure out which DBUS interface and property to use
Ed Tanouse662eae2022-01-25 10:39:19 -08001600 if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1601 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001602 {
1603 BMCWEB_LOG_DEBUG
1604 << "Invalid property value for BootSourceOverrideTarget: "
1605 << *bootSource;
1606 messages::propertyValueNotInList(aResp->res, *bootSource,
1607 "BootSourceTargetOverride");
1608 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001609 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301610
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001611 // Act on validated parameters
1612 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1613 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001614
1615 crow::connections::systemBus->async_method_call(
1616 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001617 if (ec)
1618 {
1619 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1620 messages::internalError(aResp->res);
1621 return;
1622 }
1623 BMCWEB_LOG_DEBUG << "Boot source update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001624 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001625 "xyz.openbmc_project.Settings",
1626 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001627 "org.freedesktop.DBus.Properties", "Set",
1628 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001629 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001630
1631 crow::connections::systemBus->async_method_call(
1632 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001633 if (ec)
1634 {
1635 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1636 messages::internalError(aResp->res);
1637 return;
1638 }
1639 BMCWEB_LOG_DEBUG << "Boot mode update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001640 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001641 "xyz.openbmc_project.Settings",
1642 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001643 "org.freedesktop.DBus.Properties", "Set",
1644 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001645 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001646}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001647
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001648/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001649 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301650 *
1651 * @param[in] aResp Shared pointer for generating response message.
1652 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001653 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301654 * @param[in] bootEnable The boot override enable from incoming RF request.
1655 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001656 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301657 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001658
1659inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1660 const std::optional<std::string>& bootSource,
1661 const std::optional<std::string>& bootType,
1662 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301663{
1664 BMCWEB_LOG_DEBUG << "Set boot information.";
1665
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001666 setBootModeOrSource(aResp, bootSource);
1667 setBootType(aResp, bootType);
1668 setBootEnable(aResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301669}
1670
George Liuc6a620f2020-04-10 17:18:11 +08001671/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001672 * @brief Sets AssetTag
1673 *
1674 * @param[in] aResp Shared pointer for generating response message.
1675 * @param[in] assetTag "AssetTag" from request.
1676 *
1677 * @return None.
1678 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001679inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001680 const std::string& assetTag)
1681{
George Liue99073f2022-12-09 11:06:16 +08001682 constexpr std::array<std::string_view, 1> interfaces = {
1683 "xyz.openbmc_project.Inventory.Item.System"};
1684 dbus::utility::getSubTree(
1685 "/xyz/openbmc_project/inventory", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001686 [aResp,
George Liue99073f2022-12-09 11:06:16 +08001687 assetTag](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001688 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001689 if (ec)
1690 {
1691 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1692 messages::internalError(aResp->res);
1693 return;
1694 }
1695 if (subtree.empty())
1696 {
1697 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1698 messages::internalError(aResp->res);
1699 return;
1700 }
1701 // Assume only 1 system D-Bus object
1702 // Throw an error if there is more than 1
1703 if (subtree.size() > 1)
1704 {
1705 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1706 messages::internalError(aResp->res);
1707 return;
1708 }
1709 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1710 {
1711 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1712 messages::internalError(aResp->res);
1713 return;
1714 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001715
Ed Tanous002d39b2022-05-31 08:59:27 -07001716 const std::string& path = subtree[0].first;
1717 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001718
Ed Tanous002d39b2022-05-31 08:59:27 -07001719 if (service.empty())
1720 {
1721 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1722 messages::internalError(aResp->res);
1723 return;
1724 }
1725
1726 crow::connections::systemBus->async_method_call(
1727 [aResp](const boost::system::error_code ec2) {
1728 if (ec2)
Gunnar Mills98e386e2020-10-30 14:58:09 -05001729 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001730 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1731 << ec2;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001732 messages::internalError(aResp->res);
1733 return;
1734 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001735 },
1736 service, path, "org.freedesktop.DBus.Properties", "Set",
1737 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1738 dbus::utility::DbusVariantType(assetTag));
George Liue99073f2022-12-09 11:06:16 +08001739 });
Gunnar Mills98e386e2020-10-30 14:58:09 -05001740}
1741
1742/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001743 * @brief Sets automaticRetry (Auto Reboot)
1744 *
1745 * @param[in] aResp Shared pointer for generating response message.
1746 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1747 *
1748 * @return None.
1749 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001750inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -07001751 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001752{
1753 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1754
1755 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001756 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001757
1758 if (automaticRetryConfig == "Disabled")
1759 {
1760 autoRebootEnabled = false;
1761 }
1762 else if (automaticRetryConfig == "RetryAttempts")
1763 {
1764 autoRebootEnabled = true;
1765 }
1766 else
1767 {
George Liu0fda0f12021-11-16 10:06:17 +08001768 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001769 << automaticRetryConfig;
1770 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1771 "AutomaticRetryConfig");
1772 return;
1773 }
1774
1775 crow::connections::systemBus->async_method_call(
1776 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001777 if (ec)
1778 {
1779 messages::internalError(aResp->res);
1780 return;
1781 }
Gunnar Mills69f35302020-05-17 16:06:31 -05001782 },
1783 "xyz.openbmc_project.Settings",
1784 "/xyz/openbmc_project/control/host0/auto_reboot",
1785 "org.freedesktop.DBus.Properties", "Set",
1786 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous168e20c2021-12-13 14:39:53 -08001787 dbus::utility::DbusVariantType(autoRebootEnabled));
Gunnar Mills69f35302020-05-17 16:06:31 -05001788}
1789
1790/**
George Liuc6a620f2020-04-10 17:18:11 +08001791 * @brief Sets power restore policy properties.
1792 *
1793 * @param[in] aResp Shared pointer for generating response message.
1794 * @param[in] policy power restore policy properties from request.
1795 *
1796 * @return None.
1797 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001798inline void
1799 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1800 const std::string& policy)
George Liuc6a620f2020-04-10 17:18:11 +08001801{
1802 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1803
1804 const boost::container::flat_map<std::string, std::string> policyMaps = {
George Liu0fda0f12021-11-16 10:06:17 +08001805 {"AlwaysOn",
1806 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
1807 {"AlwaysOff",
1808 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
1809 {"LastState",
1810 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
George Liuc6a620f2020-04-10 17:18:11 +08001811
1812 std::string powerRestorPolicy;
1813
Gunnar Mills4e69c902021-01-05 19:50:11 -06001814 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001815 if (policyMapsIt == policyMaps.end())
1816 {
Gunnar Mills4e69c902021-01-05 19:50:11 -06001817 messages::propertyValueNotInList(aResp->res, policy,
1818 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001819 return;
1820 }
1821
1822 powerRestorPolicy = policyMapsIt->second;
1823
1824 crow::connections::systemBus->async_method_call(
1825 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001826 if (ec)
1827 {
1828 messages::internalError(aResp->res);
1829 return;
1830 }
George Liuc6a620f2020-04-10 17:18:11 +08001831 },
1832 "xyz.openbmc_project.Settings",
1833 "/xyz/openbmc_project/control/host0/power_restore_policy",
1834 "org.freedesktop.DBus.Properties", "Set",
1835 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous168e20c2021-12-13 14:39:53 -08001836 dbus::utility::DbusVariantType(powerRestorPolicy));
George Liuc6a620f2020-04-10 17:18:11 +08001837}
1838
AppaRao Pulia6349912019-10-18 17:16:08 +05301839#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1840/**
1841 * @brief Retrieves provisioning status
1842 *
1843 * @param[in] aResp Shared pointer for completing asynchronous calls.
1844 *
1845 * @return None.
1846 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001847inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301848{
1849 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001850 sdbusplus::asio::getAllProperties(
1851 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1852 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
AppaRao Pulia6349912019-10-18 17:16:08 +05301853 [aResp](const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001854 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001855 nlohmann::json& oemPFR =
1856 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1857 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1858 "#OemComputerSystem.OpenBmc";
1859 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07001860
Ed Tanous002d39b2022-05-31 08:59:27 -07001861 if (ec)
1862 {
1863 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1864 // not an error, don't have to have the interface
1865 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1866 return;
1867 }
1868
1869 const bool* provState = nullptr;
1870 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001871
1872 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08001873 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
1874 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001875
1876 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07001877 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001878 messages::internalError(aResp->res);
1879 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07001880 }
AppaRao Pulia6349912019-10-18 17:16:08 +05301881
Ed Tanous002d39b2022-05-31 08:59:27 -07001882 if ((provState == nullptr) || (lockState == nullptr))
1883 {
1884 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1885 messages::internalError(aResp->res);
1886 return;
1887 }
AppaRao Pulia6349912019-10-18 17:16:08 +05301888
Ed Tanous002d39b2022-05-31 08:59:27 -07001889 if (*provState == true)
1890 {
1891 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05301892 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001893 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05301894 }
1895 else
1896 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001897 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05301898 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001899 }
1900 else
1901 {
1902 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1903 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001904 });
AppaRao Pulia6349912019-10-18 17:16:08 +05301905}
1906#endif
1907
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301908/**
Chris Cain3a2d04242021-05-28 16:57:10 -05001909 * @brief Translate the PowerMode to a response message.
1910 *
1911 * @param[in] aResp Shared pointer for generating response message.
1912 * @param[in] modeValue PowerMode value to be translated
1913 *
1914 * @return None.
1915 */
1916inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1917 const std::string& modeValue)
1918{
George Liu0fda0f12021-11-16 10:06:17 +08001919 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05001920 {
1921 aResp->res.jsonValue["PowerMode"] = "Static";
1922 }
George Liu0fda0f12021-11-16 10:06:17 +08001923 else if (
1924 modeValue ==
1925 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05001926 {
1927 aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
1928 }
George Liu0fda0f12021-11-16 10:06:17 +08001929 else if (modeValue ==
1930 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05001931 {
1932 aResp->res.jsonValue["PowerMode"] = "PowerSaving";
1933 }
George Liu0fda0f12021-11-16 10:06:17 +08001934 else if (modeValue ==
1935 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05001936 {
1937 aResp->res.jsonValue["PowerMode"] = "OEM";
1938 }
1939 else
1940 {
1941 // Any other values would be invalid
1942 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
1943 messages::internalError(aResp->res);
1944 }
1945}
1946
1947/**
1948 * @brief Retrieves system power mode
1949 *
1950 * @param[in] aResp Shared pointer for generating response message.
1951 *
1952 * @return None.
1953 */
1954inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1955{
1956 BMCWEB_LOG_DEBUG << "Get power mode.";
1957
1958 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08001959 constexpr std::array<std::string_view, 1> interfaces = {
1960 "xyz.openbmc_project.Control.Power.Mode"};
1961 dbus::utility::getSubTree(
1962 "/", 0, interfaces,
1963 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001964 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001965 if (ec)
1966 {
1967 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1968 << ec;
1969 // This is an optional D-Bus object so just return if
1970 // error occurs
1971 return;
1972 }
1973 if (subtree.empty())
1974 {
1975 // As noted above, this is an optional interface so just return
1976 // if there is no instance found
1977 return;
1978 }
1979 if (subtree.size() > 1)
1980 {
1981 // More then one PowerMode object is not supported and is an
1982 // error
1983 BMCWEB_LOG_DEBUG
1984 << "Found more than 1 system D-Bus Power.Mode objects: "
1985 << subtree.size();
1986 messages::internalError(aResp->res);
1987 return;
1988 }
1989 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
1990 {
1991 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
1992 messages::internalError(aResp->res);
1993 return;
1994 }
1995 const std::string& path = subtree[0].first;
1996 const std::string& service = subtree[0].second.begin()->first;
1997 if (service.empty())
1998 {
1999 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2000 messages::internalError(aResp->res);
2001 return;
2002 }
2003 // Valid Power Mode object found, now read the current value
2004 sdbusplus::asio::getProperty<std::string>(
2005 *crow::connections::systemBus, service, path,
2006 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanous8a592812022-06-04 09:06:59 -07002007 [aResp](const boost::system::error_code ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002008 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002009 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002010 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002011 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002012 << ec2;
Chris Cain3a2d04242021-05-28 16:57:10 -05002013 messages::internalError(aResp->res);
2014 return;
2015 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002016
Ed Tanous002d39b2022-05-31 08:59:27 -07002017 aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2018 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002019
Ed Tanous002d39b2022-05-31 08:59:27 -07002020 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2021 translatePowerMode(aResp, pmode);
2022 });
George Liue99073f2022-12-09 11:06:16 +08002023 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002024}
2025
2026/**
2027 * @brief Validate the specified mode is valid and return the PowerMode
2028 * name associated with that string
2029 *
2030 * @param[in] aResp Shared pointer for generating response message.
2031 * @param[in] modeString String representing the desired PowerMode
2032 *
2033 * @return PowerMode value or empty string if mode is not valid
2034 */
2035inline std::string
2036 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2037 const std::string& modeString)
2038{
2039 std::string mode;
2040
2041 if (modeString == "Static")
2042 {
2043 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2044 }
2045 else if (modeString == "MaximumPerformance")
2046 {
George Liu0fda0f12021-11-16 10:06:17 +08002047 mode =
2048 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002049 }
2050 else if (modeString == "PowerSaving")
2051 {
2052 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2053 }
2054 else
2055 {
2056 messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
2057 }
2058 return mode;
2059}
2060
2061/**
2062 * @brief Sets system power mode.
2063 *
2064 * @param[in] aResp Shared pointer for generating response message.
2065 * @param[in] pmode System power mode from request.
2066 *
2067 * @return None.
2068 */
2069inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2070 const std::string& pmode)
2071{
2072 BMCWEB_LOG_DEBUG << "Set power mode.";
2073
2074 std::string powerMode = validatePowerMode(aResp, pmode);
2075 if (powerMode.empty())
2076 {
2077 return;
2078 }
2079
2080 // Get Power Mode object path:
George Liue99073f2022-12-09 11:06:16 +08002081 constexpr std::array<std::string_view, 1> interfaces = {
2082 "xyz.openbmc_project.Control.Power.Mode"};
2083 dbus::utility::getSubTree(
2084 "/", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002085 [aResp,
George Liue99073f2022-12-09 11:06:16 +08002086 powerMode](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002087 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002088 if (ec)
2089 {
2090 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2091 << ec;
2092 // This is an optional D-Bus object, but user attempted to patch
2093 messages::internalError(aResp->res);
2094 return;
2095 }
2096 if (subtree.empty())
2097 {
2098 // This is an optional D-Bus object, but user attempted to patch
2099 messages::resourceNotFound(aResp->res, "ComputerSystem",
2100 "PowerMode");
2101 return;
2102 }
2103 if (subtree.size() > 1)
2104 {
2105 // More then one PowerMode object is not supported and is an
2106 // error
2107 BMCWEB_LOG_DEBUG
2108 << "Found more than 1 system D-Bus Power.Mode objects: "
2109 << subtree.size();
2110 messages::internalError(aResp->res);
2111 return;
2112 }
2113 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2114 {
2115 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2116 messages::internalError(aResp->res);
2117 return;
2118 }
2119 const std::string& path = subtree[0].first;
2120 const std::string& service = subtree[0].second.begin()->first;
2121 if (service.empty())
2122 {
2123 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2124 messages::internalError(aResp->res);
2125 return;
2126 }
2127
2128 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2129 << path;
2130
2131 // Set the Power Mode property
2132 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002133 [aResp](const boost::system::error_code ec2) {
2134 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002135 {
Chris Cain3a2d04242021-05-28 16:57:10 -05002136 messages::internalError(aResp->res);
2137 return;
2138 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002139 },
2140 service, path, "org.freedesktop.DBus.Properties", "Set",
2141 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2142 dbus::utility::DbusVariantType(powerMode));
George Liue99073f2022-12-09 11:06:16 +08002143 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002144}
2145
2146/**
Yong Li51709ff2019-09-30 14:13:04 +08002147 * @brief Translates watchdog timeout action DBUS property value to redfish.
2148 *
2149 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2150 *
2151 * @return Returns as a string, the timeout action in Redfish terms. If
2152 * translation cannot be done, returns an empty string.
2153 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002154inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002155{
2156 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2157 {
2158 return "None";
2159 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002160 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002161 {
2162 return "ResetSystem";
2163 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002164 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002165 {
2166 return "PowerDown";
2167 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002168 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002169 {
2170 return "PowerCycle";
2171 }
2172
2173 return "";
2174}
2175
2176/**
Yong Lic45f0082019-10-10 14:19:01 +08002177 *@brief Translates timeout action from Redfish to DBUS property value.
2178 *
2179 *@param[in] rfAction The timeout action in Redfish.
2180 *
2181 *@return Returns as a string, the time_out action as expected by DBUS.
2182 *If translation cannot be done, returns an empty string.
2183 */
2184
Ed Tanous23a21a12020-07-25 04:45:05 +00002185inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002186{
2187 if (rfAction == "None")
2188 {
2189 return "xyz.openbmc_project.State.Watchdog.Action.None";
2190 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002191 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002192 {
2193 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2194 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002195 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002196 {
2197 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2198 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002199 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002200 {
2201 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2202 }
2203
2204 return "";
2205}
2206
2207/**
Yong Li51709ff2019-09-30 14:13:04 +08002208 * @brief Retrieves host watchdog timer properties over DBUS
2209 *
2210 * @param[in] aResp Shared pointer for completing asynchronous calls.
2211 *
2212 * @return None.
2213 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002214inline void
2215 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08002216{
2217 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002218 sdbusplus::asio::getAllProperties(
2219 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2220 "/xyz/openbmc_project/watchdog/host0",
2221 "xyz.openbmc_project.State.Watchdog",
Yong Li51709ff2019-09-30 14:13:04 +08002222 [aResp](const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002223 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002224 if (ec)
2225 {
2226 // watchdog service is stopped
2227 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2228 return;
2229 }
2230
2231 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2232
2233 nlohmann::json& hostWatchdogTimer =
2234 aResp->res.jsonValue["HostWatchdogTimer"];
2235
2236 // watchdog service is running/enabled
2237 hostWatchdogTimer["Status"]["State"] = "Enabled";
2238
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002239 const bool* enabled = nullptr;
2240 const std::string* expireAction = nullptr;
2241
2242 const bool success = sdbusplus::unpackPropertiesNoThrow(
2243 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2244 "ExpireAction", expireAction);
2245
2246 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002247 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002248 messages::internalError(aResp->res);
2249 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002250 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002251
2252 if (enabled != nullptr)
2253 {
2254 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2255 }
2256
2257 if (expireAction != nullptr)
2258 {
2259 std::string action = dbusToRfWatchdogAction(*expireAction);
2260 if (action.empty())
2261 {
2262 messages::internalError(aResp->res);
2263 return;
2264 }
2265 hostWatchdogTimer["TimeoutAction"] = action;
2266 }
2267 });
Yong Li51709ff2019-09-30 14:13:04 +08002268}
2269
2270/**
Yong Lic45f0082019-10-10 14:19:01 +08002271 * @brief Sets Host WatchDog Timer properties.
2272 *
2273 * @param[in] aResp Shared pointer for generating response message.
2274 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2275 * RF request.
2276 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2277 *
2278 * @return None.
2279 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002280inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08002281 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002282 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002283{
2284 BMCWEB_LOG_DEBUG << "Set host watchdog";
2285
2286 if (wdtTimeOutAction)
2287 {
2288 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2289 // check if TimeOut Action is Valid
2290 if (wdtTimeOutActStr.empty())
2291 {
2292 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2293 << *wdtTimeOutAction;
2294 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2295 "TimeoutAction");
2296 return;
2297 }
2298
2299 crow::connections::systemBus->async_method_call(
2300 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002301 if (ec)
2302 {
2303 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2304 messages::internalError(aResp->res);
2305 return;
2306 }
Yong Lic45f0082019-10-10 14:19:01 +08002307 },
2308 "xyz.openbmc_project.Watchdog",
2309 "/xyz/openbmc_project/watchdog/host0",
2310 "org.freedesktop.DBus.Properties", "Set",
2311 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002312 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002313 }
2314
2315 if (wdtEnable)
2316 {
2317 crow::connections::systemBus->async_method_call(
2318 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002319 if (ec)
2320 {
2321 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2322 messages::internalError(aResp->res);
2323 return;
2324 }
Yong Lic45f0082019-10-10 14:19:01 +08002325 },
2326 "xyz.openbmc_project.Watchdog",
2327 "/xyz/openbmc_project/watchdog/host0",
2328 "org.freedesktop.DBus.Properties", "Set",
2329 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002330 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002331 }
2332}
2333
Chris Cain37bbf982021-09-20 10:53:09 -05002334/**
2335 * @brief Parse the Idle Power Saver properties into json
2336 *
2337 * @param[in] aResp Shared pointer for completing asynchronous calls.
2338 * @param[in] properties IPS property data from DBus.
2339 *
2340 * @return true if successful
2341 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002342inline bool
2343 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2344 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002345{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002346 const bool* enabled = nullptr;
2347 const uint8_t* enterUtilizationPercent = nullptr;
2348 const uint64_t* enterDwellTime = nullptr;
2349 const uint8_t* exitUtilizationPercent = nullptr;
2350 const uint64_t* exitDwellTime = nullptr;
2351
2352 const bool success = sdbusplus::unpackPropertiesNoThrow(
2353 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2354 "EnterUtilizationPercent", enterUtilizationPercent,
2355 "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime",
2356 exitDwellTime);
2357
2358 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002359 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002360 return false;
2361 }
2362
2363 if (enabled != nullptr)
2364 {
2365 aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
2366 }
2367
2368 if (enterUtilizationPercent != nullptr)
2369 {
2370 aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2371 *enterUtilizationPercent;
2372 }
2373
2374 if (enterDwellTime != nullptr)
2375 {
2376 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2377 aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
2378 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2379 .count();
2380 }
2381
2382 if (exitUtilizationPercent != nullptr)
2383 {
2384 aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2385 *exitUtilizationPercent;
2386 }
2387
2388 if (exitDwellTime != nullptr)
2389 {
2390 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2391 aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
2392 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2393 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002394 }
2395
2396 return true;
2397}
2398
2399/**
2400 * @brief Retrieves host watchdog timer properties over DBUS
2401 *
2402 * @param[in] aResp Shared pointer for completing asynchronous calls.
2403 *
2404 * @return None.
2405 */
2406inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
2407{
2408 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2409
2410 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002411 constexpr std::array<std::string_view, 1> interfaces = {
2412 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2413 dbus::utility::getSubTree(
2414 "/", 0, interfaces,
2415 [aResp](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002416 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002417 if (ec)
2418 {
2419 BMCWEB_LOG_DEBUG
2420 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2421 << ec;
2422 messages::internalError(aResp->res);
2423 return;
2424 }
2425 if (subtree.empty())
2426 {
2427 // This is an optional interface so just return
2428 // if there is no instance found
2429 BMCWEB_LOG_DEBUG << "No instances found";
2430 return;
2431 }
2432 if (subtree.size() > 1)
2433 {
2434 // More then one PowerIdlePowerSaver object is not supported and
2435 // is an error
2436 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2437 "Power.IdlePowerSaver objects: "
2438 << subtree.size();
2439 messages::internalError(aResp->res);
2440 return;
2441 }
2442 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2443 {
2444 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2445 messages::internalError(aResp->res);
2446 return;
2447 }
2448 const std::string& path = subtree[0].first;
2449 const std::string& service = subtree[0].second.begin()->first;
2450 if (service.empty())
2451 {
2452 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2453 messages::internalError(aResp->res);
2454 return;
2455 }
2456
2457 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002458 sdbusplus::asio::getAllProperties(
2459 *crow::connections::systemBus, service, path,
2460 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous8a592812022-06-04 09:06:59 -07002461 [aResp](const boost::system::error_code ec2,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002462 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002463 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002464 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002465 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002466 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Chris Cain37bbf982021-09-20 10:53:09 -05002467 messages::internalError(aResp->res);
2468 return;
2469 }
2470
Ed Tanous002d39b2022-05-31 08:59:27 -07002471 if (!parseIpsProperties(aResp, properties))
2472 {
2473 messages::internalError(aResp->res);
2474 return;
2475 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002476 });
George Liue99073f2022-12-09 11:06:16 +08002477 });
Chris Cain37bbf982021-09-20 10:53:09 -05002478
2479 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2480}
2481
2482/**
2483 * @brief Sets Idle Power Saver properties.
2484 *
2485 * @param[in] aResp Shared pointer for generating response message.
2486 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2487 * RF request.
2488 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2489 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2490 * before entering idle state.
2491 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2492 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2493 * before exiting idle state
2494 *
2495 * @return None.
2496 */
2497inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2498 const std::optional<bool> ipsEnable,
2499 const std::optional<uint8_t> ipsEnterUtil,
2500 const std::optional<uint64_t> ipsEnterTime,
2501 const std::optional<uint8_t> ipsExitUtil,
2502 const std::optional<uint64_t> ipsExitTime)
2503{
2504 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2505
2506 // Get IdlePowerSaver object path:
George Liue99073f2022-12-09 11:06:16 +08002507 constexpr std::array<std::string_view, 1> interfaces = {
2508 "xyz.openbmc_project.Control.Power.IdlePowerSaver"};
2509 dbus::utility::getSubTree(
2510 "/", 0, interfaces,
Chris Cain37bbf982021-09-20 10:53:09 -05002511 [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
George Liue99073f2022-12-09 11:06:16 +08002512 ipsExitTime](const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002513 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002514 if (ec)
2515 {
2516 BMCWEB_LOG_DEBUG
2517 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2518 << ec;
2519 messages::internalError(aResp->res);
2520 return;
2521 }
2522 if (subtree.empty())
2523 {
2524 // This is an optional D-Bus object, but user attempted to patch
2525 messages::resourceNotFound(aResp->res, "ComputerSystem",
2526 "IdlePowerSaver");
2527 return;
2528 }
2529 if (subtree.size() > 1)
2530 {
2531 // More then one PowerIdlePowerSaver object is not supported and
2532 // is an error
2533 BMCWEB_LOG_DEBUG
2534 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2535 << subtree.size();
2536 messages::internalError(aResp->res);
2537 return;
2538 }
2539 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2540 {
2541 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2542 messages::internalError(aResp->res);
2543 return;
2544 }
2545 const std::string& path = subtree[0].first;
2546 const std::string& service = subtree[0].second.begin()->first;
2547 if (service.empty())
2548 {
2549 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2550 messages::internalError(aResp->res);
2551 return;
2552 }
Chris Cain37bbf982021-09-20 10:53:09 -05002553
Ed Tanous002d39b2022-05-31 08:59:27 -07002554 // Valid Power IdlePowerSaver object found, now set any values that
2555 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002556
Ed Tanous002d39b2022-05-31 08:59:27 -07002557 if (ipsEnable)
2558 {
2559 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002560 [aResp](const boost::system::error_code ec2) {
2561 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002562 {
Ed Tanous8a592812022-06-04 09:06:59 -07002563 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002564 messages::internalError(aResp->res);
2565 return;
2566 }
2567 },
2568 service, path, "org.freedesktop.DBus.Properties", "Set",
2569 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2570 dbus::utility::DbusVariantType(*ipsEnable));
2571 }
2572 if (ipsEnterUtil)
2573 {
2574 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002575 [aResp](const boost::system::error_code ec2) {
2576 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002577 {
Ed Tanous8a592812022-06-04 09:06:59 -07002578 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002579 messages::internalError(aResp->res);
2580 return;
2581 }
2582 },
2583 service, path, "org.freedesktop.DBus.Properties", "Set",
2584 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2585 "EnterUtilizationPercent",
2586 dbus::utility::DbusVariantType(*ipsEnterUtil));
2587 }
2588 if (ipsEnterTime)
2589 {
2590 // Convert from seconds into milliseconds for DBus
2591 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2592 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002593 [aResp](const boost::system::error_code ec2) {
2594 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002595 {
Ed Tanous8a592812022-06-04 09:06:59 -07002596 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002597 messages::internalError(aResp->res);
2598 return;
2599 }
2600 },
2601 service, path, "org.freedesktop.DBus.Properties", "Set",
2602 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2603 "EnterDwellTime",
2604 dbus::utility::DbusVariantType(timeMilliseconds));
2605 }
2606 if (ipsExitUtil)
2607 {
2608 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002609 [aResp](const boost::system::error_code ec2) {
2610 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002611 {
Ed Tanous8a592812022-06-04 09:06:59 -07002612 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002613 messages::internalError(aResp->res);
2614 return;
2615 }
2616 },
2617 service, path, "org.freedesktop.DBus.Properties", "Set",
2618 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2619 "ExitUtilizationPercent",
2620 dbus::utility::DbusVariantType(*ipsExitUtil));
2621 }
2622 if (ipsExitTime)
2623 {
2624 // Convert from seconds into milliseconds for DBus
2625 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2626 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002627 [aResp](const boost::system::error_code ec2) {
2628 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002629 {
Ed Tanous8a592812022-06-04 09:06:59 -07002630 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002631 messages::internalError(aResp->res);
2632 return;
2633 }
2634 },
2635 service, path, "org.freedesktop.DBus.Properties", "Set",
2636 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2637 "ExitDwellTime",
2638 dbus::utility::DbusVariantType(timeMilliseconds));
2639 }
George Liue99073f2022-12-09 11:06:16 +08002640 });
Chris Cain37bbf982021-09-20 10:53:09 -05002641
2642 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2643}
2644
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002645inline void handleComputerSystemHead(
2646 crow::App& app, const crow::Request& req,
2647 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2648{
2649 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2650 {
2651 return;
2652 }
2653 asyncResp->res.addHeader(
2654 boost::beast::http::field::link,
2655 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2656}
2657
Yong Lic45f0082019-10-10 14:19:01 +08002658/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002659 * SystemsCollection derived class for delivering ComputerSystems Collection
2660 * Schema
2661 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002662inline void requestRoutesSystemsCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002663{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002664 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002665 .privileges(redfish::privileges::headComputerSystemCollection)
2666 .methods(boost::beast::http::verb::head)(
2667 std::bind_front(handleComputerSystemHead, std::ref(app)));
2668
2669 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanoused398212021-06-09 17:05:54 -07002670 .privileges(redfish::privileges::getComputerSystemCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002671 .methods(boost::beast::http::verb::get)(
Ed Tanousf4c99e72021-10-04 17:02:43 -07002672 [&app](const crow::Request& req,
2673 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002674 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002675 {
2676 return;
2677 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002678
2679 asyncResp->res.addHeader(
2680 boost::beast::http::field::link,
2681 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002682 asyncResp->res.jsonValue["@odata.type"] =
2683 "#ComputerSystemCollection.ComputerSystemCollection";
2684 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2685 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002686
Ed Tanous002d39b2022-05-31 08:59:27 -07002687 sdbusplus::asio::getProperty<std::string>(
2688 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2689 "/xyz/openbmc_project/network/hypervisor",
2690 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
Ed Tanous8a592812022-06-04 09:06:59 -07002691 [asyncResp](const boost::system::error_code ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002692 const std::string& /*hostName*/) {
2693 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2694 ifaceArray = nlohmann::json::array();
2695 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Ed Tanous14766872022-03-15 10:44:42 -07002696
Ed Tanous002d39b2022-05-31 08:59:27 -07002697 nlohmann::json::object_t system;
2698 system["@odata.id"] = "/redfish/v1/Systems/system";
2699 ifaceArray.push_back(std::move(system));
2700 count = ifaceArray.size();
Ed Tanous8a592812022-06-04 09:06:59 -07002701 if (!ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002702 {
2703 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2704 nlohmann::json::object_t hypervisor;
2705 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2706 ifaceArray.push_back(std::move(hypervisor));
2707 count = ifaceArray.size();
2708 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002709 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002710 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002711}
Sunitha Harish462023a2020-02-19 08:34:59 -06002712
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002713/**
2714 * Function transceives data with dbus directly.
2715 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002716inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002717{
2718 constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2719 constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2720 constexpr char const* interfaceName =
2721 "xyz.openbmc_project.Control.Host.NMI";
2722 constexpr char const* method = "NMI";
2723
2724 crow::connections::systemBus->async_method_call(
2725 [asyncResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002726 if (ec)
2727 {
2728 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2729 messages::internalError(asyncResp->res);
2730 return;
2731 }
2732 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002733 },
2734 serviceName, objectPath, interfaceName, method);
2735}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002736
2737/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002738 * SystemActionsReset class supports handle POST method for Reset action.
2739 * The class retrieves and sends data directly to D-Bus.
2740 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002741inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002742{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002743 /**
2744 * Function handles POST method request.
2745 * Analyzes POST body message before sends Reset request data to D-Bus.
2746 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002747 BMCWEB_ROUTE(app,
2748 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002749 .privileges(redfish::privileges::postComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002750 .methods(boost::beast::http::verb::post)(
2751 [&app](const crow::Request& req,
2752 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002753 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002754 {
2755 return;
2756 }
2757 std::string resetType;
2758 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
2759 resetType))
2760 {
2761 return;
2762 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002763
Ed Tanous002d39b2022-05-31 08:59:27 -07002764 // Get the command and host vs. chassis
2765 std::string command;
2766 bool hostCommand = true;
2767 if ((resetType == "On") || (resetType == "ForceOn"))
2768 {
2769 command = "xyz.openbmc_project.State.Host.Transition.On";
2770 hostCommand = true;
2771 }
2772 else if (resetType == "ForceOff")
2773 {
2774 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2775 hostCommand = false;
2776 }
2777 else if (resetType == "ForceRestart")
2778 {
2779 command =
2780 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2781 hostCommand = true;
2782 }
2783 else if (resetType == "GracefulShutdown")
2784 {
2785 command = "xyz.openbmc_project.State.Host.Transition.Off";
2786 hostCommand = true;
2787 }
2788 else if (resetType == "GracefulRestart")
2789 {
2790 command =
2791 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2792 hostCommand = true;
2793 }
2794 else if (resetType == "PowerCycle")
2795 {
2796 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2797 hostCommand = true;
2798 }
2799 else if (resetType == "Nmi")
2800 {
2801 doNMI(asyncResp);
2802 return;
2803 }
2804 else
2805 {
2806 messages::actionParameterUnknown(asyncResp->res, "Reset",
2807 resetType);
2808 return;
2809 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002810
Ed Tanous002d39b2022-05-31 08:59:27 -07002811 if (hostCommand)
2812 {
2813 crow::connections::systemBus->async_method_call(
2814 [asyncResp, resetType](const boost::system::error_code ec) {
2815 if (ec)
2816 {
2817 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2818 if (ec.value() == boost::asio::error::invalid_argument)
2819 {
2820 messages::actionParameterNotSupported(
2821 asyncResp->res, resetType, "Reset");
2822 }
2823 else
2824 {
2825 messages::internalError(asyncResp->res);
2826 }
2827 return;
2828 }
2829 messages::success(asyncResp->res);
2830 },
2831 "xyz.openbmc_project.State.Host",
2832 "/xyz/openbmc_project/state/host0",
2833 "org.freedesktop.DBus.Properties", "Set",
2834 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2835 dbus::utility::DbusVariantType{command});
2836 }
2837 else
2838 {
2839 crow::connections::systemBus->async_method_call(
2840 [asyncResp, resetType](const boost::system::error_code ec) {
2841 if (ec)
2842 {
2843 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2844 if (ec.value() == boost::asio::error::invalid_argument)
2845 {
2846 messages::actionParameterNotSupported(
2847 asyncResp->res, resetType, "Reset");
2848 }
2849 else
2850 {
2851 messages::internalError(asyncResp->res);
2852 }
2853 return;
2854 }
2855 messages::success(asyncResp->res);
2856 },
2857 "xyz.openbmc_project.State.Chassis",
2858 "/xyz/openbmc_project/state/chassis0",
2859 "org.freedesktop.DBus.Properties", "Set",
2860 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2861 dbus::utility::DbusVariantType{command});
2862 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002863 });
2864}
Ed Tanouscc340dd2018-08-29 13:43:38 -07002865
Ed Tanous38c8a6f2022-09-01 16:37:27 -07002866inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002867 App& app, const crow::Request& req,
2868 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2869{
2870 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2871 {
2872 return;
2873 }
2874
2875 asyncResp->res.addHeader(
2876 boost::beast::http::field::link,
2877 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2878}
2879
Ed Tanouscc340dd2018-08-29 13:43:38 -07002880/**
Ed Tanous66173382018-08-15 18:20:59 -07002881 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002882 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002883inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002884{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002885
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002886 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2887 .privileges(redfish::privileges::headComputerSystem)
2888 .methods(boost::beast::http::verb::head)(
2889 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002890 /**
2891 * Functions triggers appropriate requests on DBus
2892 */
Ed Tanous22d268c2022-05-19 09:39:07 -07002893 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002894 .privileges(redfish::privileges::getComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002895 .methods(boost::beast::http::verb::get)(
2896 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002897 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2898 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002899 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002900 {
2901 return;
2902 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002903 if (systemName != "system")
2904 {
2905 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2906 systemName);
2907 return;
2908 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002909 asyncResp->res.addHeader(
2910 boost::beast::http::field::link,
2911 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002912 asyncResp->res.jsonValue["@odata.type"] =
2913 "#ComputerSystem.v1_16_0.ComputerSystem";
2914 asyncResp->res.jsonValue["Name"] = "system";
2915 asyncResp->res.jsonValue["Id"] = "system";
2916 asyncResp->res.jsonValue["SystemType"] = "Physical";
2917 asyncResp->res.jsonValue["Description"] = "Computer System";
2918 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
2919 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
2920 "Disabled";
2921 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
2922 uint64_t(0);
2923 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
2924 "Disabled";
2925 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07002926
Ed Tanous002d39b2022-05-31 08:59:27 -07002927 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
2928 "/redfish/v1/Systems/system/Processors";
2929 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
2930 "/redfish/v1/Systems/system/Memory";
2931 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
2932 "/redfish/v1/Systems/system/Storage";
Ed Tanous029573d2019-02-01 10:57:49 -08002933
Ed Tanous002d39b2022-05-31 08:59:27 -07002934 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
2935 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
2936 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
2937 ["@Redfish.ActionInfo"] =
2938 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002939
Ed Tanous002d39b2022-05-31 08:59:27 -07002940 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
2941 "/redfish/v1/Systems/system/LogServices";
2942 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
2943 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08002944
Ed Tanous002d39b2022-05-31 08:59:27 -07002945 nlohmann::json::array_t managedBy;
2946 nlohmann::json& manager = managedBy.emplace_back();
2947 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
2948 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
2949 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
2950 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002951
Ed Tanous002d39b2022-05-31 08:59:27 -07002952 // Fill in SerialConsole info
2953 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
2954 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
2955 true;
Ed Tanous14766872022-03-15 10:44:42 -07002956
Ed Tanous002d39b2022-05-31 08:59:27 -07002957 // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
2958 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
2959 true;
2960 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
2961 asyncResp->res
2962 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
2963 "Press ~. to exit console";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002964
2965#ifdef BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07002966 // Fill in GraphicalConsole info
2967 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
2968 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
2969 4;
Ed Tanous613dabe2022-07-09 11:17:36 -07002970 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
2971 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07002972
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002973#endif // BMCWEB_ENABLE_KVM
George Liu7a1dbc42022-12-07 16:03:22 +08002974 constexpr std::array<std::string_view, 4> inventoryForSystems{
Ed Tanous002d39b2022-05-31 08:59:27 -07002975 "xyz.openbmc_project.Inventory.Item.Dimm",
2976 "xyz.openbmc_project.Inventory.Item.Cpu",
2977 "xyz.openbmc_project.Inventory.Item.Drive",
2978 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07002979
Ed Tanous002d39b2022-05-31 08:59:27 -07002980 auto health = std::make_shared<HealthPopulate>(asyncResp);
George Liu7a1dbc42022-12-07 16:03:22 +08002981 dbus::utility::getSubTreePaths(
2982 "/", 0, inventoryForSystems,
2983 [health](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -07002984 const std::vector<std::string>& resp) {
2985 if (ec)
2986 {
2987 // no inventory
2988 return;
2989 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002990
Ed Tanous002d39b2022-05-31 08:59:27 -07002991 health->inventory = resp;
George Liu7a1dbc42022-12-07 16:03:22 +08002992 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002993
Ed Tanous002d39b2022-05-31 08:59:27 -07002994 health->populate();
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002995
Ed Tanous002d39b2022-05-31 08:59:27 -07002996 getMainChassisId(asyncResp,
2997 [](const std::string& chassisId,
2998 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
2999 nlohmann::json::array_t chassisArray;
3000 nlohmann::json& chassis = chassisArray.emplace_back();
3001 chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId;
3002 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3003 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003004
Ed Tanous002d39b2022-05-31 08:59:27 -07003005 getLocationIndicatorActive(asyncResp);
3006 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3007 getIndicatorLedState(asyncResp);
3008 getComputerSystem(asyncResp, health);
3009 getHostState(asyncResp);
3010 getBootProperties(asyncResp);
3011 getBootProgress(asyncResp);
Hieu Huynhb6d5d452022-10-07 09:41:46 +00003012 getBootProgressLastStateTime(asyncResp);
Ed Tanous002d39b2022-05-31 08:59:27 -07003013 getPCIeDeviceList(asyncResp, "PCIeDevices");
3014 getHostWatchdogTimer(asyncResp);
3015 getPowerRestorePolicy(asyncResp);
3016 getAutomaticRetry(asyncResp);
3017 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003018#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanous002d39b2022-05-31 08:59:27 -07003019 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003020#endif
Ed Tanous002d39b2022-05-31 08:59:27 -07003021 getTrustedModuleRequiredToBoot(asyncResp);
3022 getPowerMode(asyncResp);
3023 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003024 });
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003025
Ed Tanous22d268c2022-05-19 09:39:07 -07003026 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003027 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003028 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003029 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003030 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3031 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003032 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003033 {
3034 return;
3035 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003036 if (systemName != "system")
3037 {
3038 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3039 systemName);
3040 return;
3041 }
3042
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003043 asyncResp->res.addHeader(
3044 boost::beast::http::field::link,
3045 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3046
Ed Tanous002d39b2022-05-31 08:59:27 -07003047 std::optional<bool> locationIndicatorActive;
3048 std::optional<std::string> indicatorLed;
3049 std::optional<std::string> assetTag;
3050 std::optional<std::string> powerRestorePolicy;
3051 std::optional<std::string> powerMode;
3052 std::optional<bool> wdtEnable;
3053 std::optional<std::string> wdtTimeOutAction;
3054 std::optional<std::string> bootSource;
3055 std::optional<std::string> bootType;
3056 std::optional<std::string> bootEnable;
3057 std::optional<std::string> bootAutomaticRetry;
3058 std::optional<bool> bootTrustedModuleRequired;
3059 std::optional<bool> ipsEnable;
3060 std::optional<uint8_t> ipsEnterUtil;
3061 std::optional<uint64_t> ipsEnterTime;
3062 std::optional<uint8_t> ipsExitUtil;
3063 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003064
Ed Tanous002d39b2022-05-31 08:59:27 -07003065 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003066 if (!json_util::readJsonPatch(
3067 req, asyncResp->res,
3068 "IndicatorLED", indicatorLed,
3069 "LocationIndicatorActive", locationIndicatorActive,
3070 "AssetTag", assetTag,
3071 "PowerRestorePolicy", powerRestorePolicy,
3072 "PowerMode", powerMode,
3073 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3074 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3075 "Boot/BootSourceOverrideTarget", bootSource,
3076 "Boot/BootSourceOverrideMode", bootType,
3077 "Boot/BootSourceOverrideEnabled", bootEnable,
3078 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3079 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3080 "IdlePowerSaver/Enabled", ipsEnable,
3081 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3082 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3083 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3084 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3085 {
3086 return;
3087 }
Ed Tanous002d39b2022-05-31 08:59:27 -07003088 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003089
Ed Tanous002d39b2022-05-31 08:59:27 -07003090 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003091
Ed Tanous002d39b2022-05-31 08:59:27 -07003092 if (assetTag)
3093 {
3094 setAssetTag(asyncResp, *assetTag);
3095 }
James Feistb49ac872019-05-21 15:12:01 -07003096
Ed Tanous002d39b2022-05-31 08:59:27 -07003097 if (wdtEnable || wdtTimeOutAction)
3098 {
3099 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3100 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003101
Ed Tanous002d39b2022-05-31 08:59:27 -07003102 if (bootSource || bootType || bootEnable)
3103 {
3104 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3105 }
3106 if (bootAutomaticRetry)
3107 {
3108 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3109 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003110
Ed Tanous002d39b2022-05-31 08:59:27 -07003111 if (bootTrustedModuleRequired)
3112 {
3113 setTrustedModuleRequiredToBoot(asyncResp,
3114 *bootTrustedModuleRequired);
3115 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003116
Ed Tanous002d39b2022-05-31 08:59:27 -07003117 if (locationIndicatorActive)
3118 {
3119 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3120 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003121
Ed Tanous002d39b2022-05-31 08:59:27 -07003122 // TODO (Gunnar): Remove IndicatorLED after enough time has
3123 // passed
3124 if (indicatorLed)
3125 {
3126 setIndicatorLedState(asyncResp, *indicatorLed);
3127 asyncResp->res.addHeader(boost::beast::http::field::warning,
3128 "299 - \"IndicatorLED is deprecated. Use "
3129 "LocationIndicatorActive instead.\"");
3130 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003131
Ed Tanous002d39b2022-05-31 08:59:27 -07003132 if (powerRestorePolicy)
3133 {
3134 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3135 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003136
Ed Tanous002d39b2022-05-31 08:59:27 -07003137 if (powerMode)
3138 {
3139 setPowerMode(asyncResp, *powerMode);
3140 }
Chris Cain37bbf982021-09-20 10:53:09 -05003141
Ed Tanous002d39b2022-05-31 08:59:27 -07003142 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3143 ipsExitTime)
3144 {
3145 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3146 ipsExitUtil, ipsExitTime);
3147 }
3148 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003149}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303150
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003151inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003152 crow::App& app, const crow::Request& req,
3153 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3154{
3155 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3156 {
3157 return;
3158 }
3159 asyncResp->res.addHeader(
3160 boost::beast::http::field::link,
3161 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3162}
3163
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303164/**
3165 * SystemResetActionInfo derived class for delivering Computer Systems
3166 * ResetType AllowableValues using ResetInfo schema.
3167 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003168inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303169{
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003170 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3171 .privileges(redfish::privileges::headActionInfo)
3172 .methods(boost::beast::http::verb::head)(std::bind_front(
3173 handleSystemCollectionResetActionHead, std::ref(app)));
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303174 /**
3175 * Functions triggers appropriate requests on DBus
3176 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003177 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003178 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003179 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003180 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003181 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3182 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003183 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003184 {
3185 return;
3186 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003187 if (systemName != "system")
3188 {
3189 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3190 systemName);
3191 return;
3192 }
3193
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003194 asyncResp->res.addHeader(
3195 boost::beast::http::field::link,
3196 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
Ed Tanous14766872022-03-15 10:44:42 -07003197
Ed Tanous002d39b2022-05-31 08:59:27 -07003198 asyncResp->res.jsonValue["@odata.id"] =
3199 "/redfish/v1/Systems/system/ResetActionInfo";
3200 asyncResp->res.jsonValue["@odata.type"] =
3201 "#ActionInfo.v1_1_2.ActionInfo";
3202 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3203 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
Nan Zhou3215e702022-06-01 16:55:13 +00003204
3205 nlohmann::json::array_t parameters;
3206 nlohmann::json::object_t parameter;
3207
3208 parameter["Name"] = "ResetType";
3209 parameter["Required"] = true;
3210 parameter["DataType"] = "String";
3211 nlohmann::json::array_t allowableValues;
3212 allowableValues.emplace_back("On");
3213 allowableValues.emplace_back("ForceOff");
3214 allowableValues.emplace_back("ForceOn");
3215 allowableValues.emplace_back("ForceRestart");
3216 allowableValues.emplace_back("GracefulRestart");
3217 allowableValues.emplace_back("GracefulShutdown");
3218 allowableValues.emplace_back("PowerCycle");
3219 allowableValues.emplace_back("Nmi");
3220 parameter["AllowableValues"] = std::move(allowableValues);
3221 parameters.emplace_back(std::move(parameter));
3222
3223 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
Ed Tanous002d39b2022-05-31 08:59:27 -07003224 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003225}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003226} // namespace redfish