blob: e476592c27483ddd31e1b76d1521b9fc3b150c29 [file] [log] [blame]
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Jonathan Doman1e1e5982021-06-11 09:36:17 -070018#include "dbus_singleton.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080019#include "dbus_utility.hpp"
James Feistb49ac872019-05-21 15:12:01 -070020#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080021#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080022#include "pcie.hpp"
Ed Tanousf4c99e72021-10-04 17:02:43 -070023#include "query.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080024#include "redfish_util.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070025#include "utils/time_utils.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080026
John Edward Broadbent7e860f12021-04-08 15:57:16 -070027#include <app.hpp>
Ed Tanous9712f8a2018-09-21 13:38:49 -070028#include <boost/container/flat_map.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070029#include <registries/privilege_registry.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070030#include <sdbusplus/asio/property.hpp>
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +020031#include <sdbusplus/unpack_properties.hpp>
32#include <utils/dbus_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020033#include <utils/json_utils.hpp>
Willy Tueee00132022-06-14 14:53:17 -070034#include <utils/sw_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050035
George Liu7a1dbc42022-12-07 16:03:22 +080036#include <array>
37#include <string_view>
Ed Tanousabf2add2019-01-22 16:40:12 -080038#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020039
Ed Tanous1abe55e2018-09-05 08:30:59 -070040namespace redfish
41{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020042
Alpana Kumari9d3ae102019-04-12 06:49:32 -050043/**
44 * @brief Updates the Functional State of DIMMs
45 *
46 * @param[in] aResp Shared pointer for completing asynchronous calls
47 * @param[in] dimmState Dimm's Functional state, true/false
48 *
49 * @return None.
50 */
zhanghch058d1b46d2021-04-01 11:18:24 +080051inline void
52 updateDimmProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Jonathan Doman1e1e5982021-06-11 09:36:17 -070053 bool isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050054{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070055 BMCWEB_LOG_DEBUG << "Dimm Functional: " << isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056
Gunnar Mills4e0453b2020-07-08 14:00:30 -050057 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050058 // Update STATE only if previous State was DISABLED and current Dimm is
59 // ENABLED.
Ed Tanous02cad962022-06-30 16:50:15 -070060 const nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050061 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
62 if (prevMemSummary == "Disabled")
63 {
Ed Tanouse05aec52022-01-25 10:28:56 -080064 if (isDimmFunctional)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050065 {
66 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
67 "Enabled";
68 }
69 }
70}
71
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050072/*
73 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
74 *
75 * @param[in] aResp Shared pointer for completing asynchronous calls
76 * @param[in] cpuPresenceState CPU present or not
77 *
78 * @return None.
79 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -070080inline void
81 modifyCpuPresenceState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
82 bool isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050083{
Jonathan Doman1e1e5982021-06-11 09:36:17 -070084 BMCWEB_LOG_DEBUG << "Cpu Present: " << isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085
Ed Tanous55f79e62022-01-25 11:26:16 -080086 if (isCpuPresent)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050087 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050088 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080089 aResp->res.jsonValue["ProcessorSummary"]["Count"];
Ed Tanous55f79e62022-01-25 11:26:16 -080090 auto* procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050091 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080092 if (procCountPtr != nullptr)
93 {
94 // shouldn't be possible to be nullptr
95 *procCountPtr += 1;
96 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050097 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098}
99
100/*
101 * @brief Update "ProcessorSummary" "Status" "State" based on
102 * CPU Functional State
103 *
104 * @param[in] aResp Shared pointer for completing asynchronous calls
105 * @param[in] cpuFunctionalState is CPU functional true/false
106 *
107 * @return None.
108 */
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700109inline void
110 modifyCpuFunctionalState(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
111 bool isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500112{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700113 BMCWEB_LOG_DEBUG << "Cpu Functional: " << isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114
Ed Tanous02cad962022-06-30 16:50:15 -0700115 const nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500116 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
117
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500118 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500119 // Update STATE only if previous State was Non_Functional and current CPU is
120 // Functional.
121 if (prevProcState == "Disabled")
122 {
Ed Tanouse05aec52022-01-25 10:28:56 -0800123 if (isCpuFunctional)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500124 {
125 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
126 "Enabled";
127 }
128 }
129}
130
Ali Ahmed382d6472021-09-03 16:53:53 -0500131inline void getProcessorProperties(
132 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
133 const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
134 properties)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500135{
136
137 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " Cpu properties.";
138
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200139 // TODO: Get Model
140
141 const uint16_t* coreCount = nullptr;
142
143 const bool success = sdbusplus::unpackPropertiesNoThrow(
144 dbus_utils::UnpackErrorPrinter(), properties, "CoreCount", coreCount);
145
146 if (!success)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500147 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200148 messages::internalError(aResp->res);
149 return;
150 }
Ali Ahmed03fbed92021-09-03 02:33:43 -0500151
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200152 if (coreCount != nullptr)
153 {
154 nlohmann::json& coreCountJson =
155 aResp->res.jsonValue["ProcessorSummary"]["CoreCount"];
156 uint64_t* coreCountJsonPtr = coreCountJson.get_ptr<uint64_t*>();
Ali Ahmed03fbed92021-09-03 02:33:43 -0500157
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200158 if (coreCountJsonPtr == nullptr)
Ali Ahmed03fbed92021-09-03 02:33:43 -0500159 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200160 coreCountJson = *coreCount;
161 }
162 else
163 {
164 *coreCountJsonPtr += *coreCount;
Ali Ahmed03fbed92021-09-03 02:33:43 -0500165 }
166 }
167}
168
169/*
170 * @brief Get ProcessorSummary fields
171 *
172 * @param[in] aResp Shared pointer for completing asynchronous calls
173 * @param[in] service dbus service for Cpu Information
174 * @param[in] path dbus path for Cpu
175 *
176 * @return None.
177 */
178inline void getProcessorSummary(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
179 const std::string& service,
180 const std::string& path)
181{
182
Ali Ahmed382d6472021-09-03 16:53:53 -0500183 auto getCpuPresenceState = [aResp](const boost::system::error_code ec3,
184 const bool cpuPresenceCheck) {
185 if (ec3)
186 {
187 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
188 return;
189 }
190 modifyCpuPresenceState(aResp, cpuPresenceCheck);
191 };
192
193 auto getCpuFunctionalState = [aResp](const boost::system::error_code ec3,
194 const bool cpuFunctionalCheck) {
195 if (ec3)
196 {
197 BMCWEB_LOG_ERROR << "DBUS response error " << ec3;
198 return;
199 }
200 modifyCpuFunctionalState(aResp, cpuFunctionalCheck);
201 };
202
203 // Get the Presence of CPU
204 sdbusplus::asio::getProperty<bool>(
205 *crow::connections::systemBus, service, path,
206 "xyz.openbmc_project.Inventory.Item", "Present",
207 std::move(getCpuPresenceState));
208
209 // Get the Functional State
210 sdbusplus::asio::getProperty<bool>(
211 *crow::connections::systemBus, service, path,
212 "xyz.openbmc_project.State.Decorator.OperationalStatus", "Functional",
213 std::move(getCpuFunctionalState));
214
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200215 sdbusplus::asio::getAllProperties(
216 *crow::connections::systemBus, service, path,
217 "xyz.openbmc_project.Inventory.Item.Cpu",
Ali Ahmed03fbed92021-09-03 02:33:43 -0500218 [aResp, service,
219 path](const boost::system::error_code ec2,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800220 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700221 if (ec2)
222 {
223 BMCWEB_LOG_ERROR << "DBUS response error " << ec2;
224 messages::internalError(aResp->res);
225 return;
226 }
Ali Ahmed382d6472021-09-03 16:53:53 -0500227 getProcessorProperties(aResp, properties);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200228 });
Ali Ahmed03fbed92021-09-03 02:33:43 -0500229}
230
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500231/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700232 * @brief Retrieves computer system properties over dbus
233 *
234 * @param[in] aResp Shared pointer for completing asynchronous calls
Gunnar Mills8f9ee3c2020-10-30 16:15:13 -0500235 * @param[in] systemHealth Shared HealthPopulate pointer
Ed Tanous6c34de42018-08-29 13:37:36 -0700236 *
237 * @return None.
238 */
Ed Tanousb5a76932020-09-29 16:16:58 -0700239inline void
zhanghch058d1b46d2021-04-01 11:18:24 +0800240 getComputerSystem(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousb5a76932020-09-29 16:16:58 -0700241 const std::shared_ptr<HealthPopulate>& systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700242{
Ed Tanous6c34de42018-08-29 13:37:36 -0700243 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500244
Ed Tanous6c34de42018-08-29 13:37:36 -0700245 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -0800246 [aResp,
247 systemHealth](const boost::system::error_code ec,
248 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700249 if (ec)
250 {
251 BMCWEB_LOG_DEBUG << "DBUS response error";
252 messages::internalError(aResp->res);
253 return;
254 }
255 // Iterate over all retrieved ObjectPaths.
256 for (const std::pair<
257 std::string,
258 std::vector<std::pair<std::string, std::vector<std::string>>>>&
259 object : subtree)
260 {
261 const std::string& path = object.first;
262 BMCWEB_LOG_DEBUG << "Got path: " << path;
263 const std::vector<std::pair<std::string, std::vector<std::string>>>&
264 connectionNames = object.second;
265 if (connectionNames.empty())
Ed Tanous6c34de42018-08-29 13:37:36 -0700266 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700267 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700268 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700269
270 auto memoryHealth = std::make_shared<HealthPopulate>(
271 aResp, "/MemorySummary/Status"_json_pointer);
272
273 auto cpuHealth = std::make_shared<HealthPopulate>(
274 aResp, "/ProcessorSummary/Status"_json_pointer);
275
276 systemHealth->children.emplace_back(memoryHealth);
277 systemHealth->children.emplace_back(cpuHealth);
278
279 // This is not system, so check if it's cpu, dimm, UUID or
280 // BiosVer
281 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700282 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700283 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700284 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700285 if (interfaceName ==
286 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700287 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700288 BMCWEB_LOG_DEBUG
289 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500290
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200291 sdbusplus::asio::getAllProperties(
292 *crow::connections::systemBus, connection.first,
293 path, "xyz.openbmc_project.Inventory.Item.Dimm",
Ed Tanous002d39b2022-05-31 08:59:27 -0700294 [aResp, service{connection.first},
295 path](const boost::system::error_code ec2,
296 const dbus::utility::DBusPropertiesMap&
297 properties) {
298 if (ec2)
299 {
300 BMCWEB_LOG_ERROR << "DBUS response error "
301 << ec2;
302 messages::internalError(aResp->res);
303 return;
304 }
305 BMCWEB_LOG_DEBUG << "Got " << properties.size()
306 << " Dimm properties.";
307
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200308 if (properties.empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700309 {
310 sdbusplus::asio::getProperty<bool>(
311 *crow::connections::systemBus, service,
312 path,
313 "xyz.openbmc_project.State."
314 "Decorator.OperationalStatus",
315 "Functional",
316 [aResp](const boost::system::error_code ec3,
317 bool dimmState) {
318 if (ec3)
319 {
320 BMCWEB_LOG_ERROR
Ed Tanouscb13a392020-07-25 19:02:03 +0000321 << "DBUS response error " << ec3;
Ed Tanous029573d2019-02-01 10:57:49 -0800322 return;
323 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700324 updateDimmProperties(aResp, dimmState);
325 });
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200326 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700327 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200328
329 const uint32_t* memorySizeInKB = nullptr;
330
331 const bool success =
332 sdbusplus::unpackPropertiesNoThrow(
333 dbus_utils::UnpackErrorPrinter(),
334 properties, "MemorySizeInKB",
335 memorySizeInKB);
336
337 if (!success)
338 {
339 messages::internalError(aResp->res);
340 return;
341 }
342
343 if (memorySizeInKB != nullptr)
344 {
345 nlohmann::json& totalMemory =
346 aResp->res
347 .jsonValue["MemorySummary"]
348 ["TotalSystemMemoryGiB"];
349 const uint64_t* preValue =
350 totalMemory.get_ptr<const uint64_t*>();
351 if (preValue == nullptr)
352 {
353 aResp->res
354 .jsonValue["MemorySummary"]
355 ["TotalSystemMemoryGiB"] =
356 *memorySizeInKB / (1024 * 1024);
357 }
358 else
359 {
360 aResp->res
361 .jsonValue["MemorySummary"]
362 ["TotalSystemMemoryGiB"] =
363 *memorySizeInKB / (1024 * 1024) +
364 *preValue;
365 }
366 aResp->res.jsonValue["MemorySummary"]["Status"]
367 ["State"] = "Enabled";
368 }
369 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700370
371 memoryHealth->inventory.emplace_back(path);
372 }
373 else if (interfaceName ==
374 "xyz.openbmc_project.Inventory.Item.Cpu")
375 {
376 BMCWEB_LOG_DEBUG
377 << "Found Cpu, now get its properties.";
378
379 getProcessorSummary(aResp, connection.first, path);
380
381 cpuHealth->inventory.emplace_back(path);
382 }
383 else if (interfaceName == "xyz.openbmc_project.Common.UUID")
384 {
385 BMCWEB_LOG_DEBUG
386 << "Found UUID, now get its properties.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200387
388 sdbusplus::asio::getAllProperties(
389 *crow::connections::systemBus, connection.first,
390 path, "xyz.openbmc_project.Common.UUID",
Ed Tanous002d39b2022-05-31 08:59:27 -0700391 [aResp](const boost::system::error_code ec3,
392 const dbus::utility::DBusPropertiesMap&
393 properties) {
394 if (ec3)
395 {
396 BMCWEB_LOG_DEBUG << "DBUS response error "
397 << ec3;
398 messages::internalError(aResp->res);
399 return;
400 }
401 BMCWEB_LOG_DEBUG << "Got " << properties.size()
402 << " UUID properties.";
Ed Tanous002d39b2022-05-31 08:59:27 -0700403
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200404 const std::string* uUID = nullptr;
405
406 const bool success =
407 sdbusplus::unpackPropertiesNoThrow(
408 dbus_utils::UnpackErrorPrinter(),
409 properties, "UUID", uUID);
410
411 if (!success)
412 {
413 messages::internalError(aResp->res);
414 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700415 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200416
417 if (uUID != nullptr)
418 {
419 std::string valueStr = *uUID;
420 if (valueStr.size() == 32)
421 {
422 valueStr.insert(8, 1, '-');
423 valueStr.insert(13, 1, '-');
424 valueStr.insert(18, 1, '-');
425 valueStr.insert(23, 1, '-');
426 }
427 BMCWEB_LOG_DEBUG << "UUID = " << valueStr;
428 aResp->res.jsonValue["UUID"] = valueStr;
429 }
430 });
Ed Tanous002d39b2022-05-31 08:59:27 -0700431 }
432 else if (interfaceName ==
433 "xyz.openbmc_project.Inventory.Item.System")
434 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200435 sdbusplus::asio::getAllProperties(
436 *crow::connections::systemBus, connection.first,
437 path,
438 "xyz.openbmc_project.Inventory.Decorator.Asset",
Ed Tanous002d39b2022-05-31 08:59:27 -0700439 [aResp](const boost::system::error_code ec2,
440 const dbus::utility::DBusPropertiesMap&
441 propertiesList) {
442 if (ec2)
443 {
444 // doesn't have to include this
445 // interface
446 return;
447 }
448 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
449 << " properties for system";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200450
451 const std::string* partNumber = nullptr;
452 const std::string* serialNumber = nullptr;
453 const std::string* manufacturer = nullptr;
454 const std::string* model = nullptr;
455 const std::string* subModel = nullptr;
456
457 const bool success =
458 sdbusplus::unpackPropertiesNoThrow(
459 dbus_utils::UnpackErrorPrinter(),
460 propertiesList, "PartNumber", partNumber,
461 "SerialNumber", serialNumber,
462 "Manufacturer", manufacturer, "Model",
463 model, "SubModel", subModel);
464
465 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700466 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200467 messages::internalError(aResp->res);
468 return;
469 }
470
471 if (partNumber != nullptr)
472 {
473 aResp->res.jsonValue["PartNumber"] =
474 *partNumber;
475 }
476
477 if (serialNumber != nullptr)
478 {
479 aResp->res.jsonValue["SerialNumber"] =
480 *serialNumber;
481 }
482
483 if (manufacturer != nullptr)
484 {
485 aResp->res.jsonValue["Manufacturer"] =
486 *manufacturer;
487 }
488
489 if (model != nullptr)
490 {
491 aResp->res.jsonValue["Model"] = *model;
492 }
493
494 if (subModel != nullptr)
495 {
496 aResp->res.jsonValue["SubModel"] = *subModel;
Ed Tanous002d39b2022-05-31 08:59:27 -0700497 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500498
Ed Tanous002d39b2022-05-31 08:59:27 -0700499 // Grab the bios version
Willy Tueee00132022-06-14 14:53:17 -0700500 sw_util::populateSoftwareInformation(
501 aResp, sw_util::biosPurpose, "BiosVersion",
Ed Tanous002d39b2022-05-31 08:59:27 -0700502 false);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200503 });
James Feiste4a4b9a2019-06-20 14:08:07 -0700504
Ed Tanous002d39b2022-05-31 08:59:27 -0700505 sdbusplus::asio::getProperty<std::string>(
506 *crow::connections::systemBus, connection.first,
507 path,
508 "xyz.openbmc_project.Inventory.Decorator."
509 "AssetTag",
510 "AssetTag",
511 [aResp](const boost::system::error_code ec2,
512 const std::string& value) {
513 if (ec2)
514 {
515 // doesn't have to include this
516 // interface
517 return;
518 }
James Feiste4a4b9a2019-06-20 14:08:07 -0700519
Ed Tanous002d39b2022-05-31 08:59:27 -0700520 aResp->res.jsonValue["AssetTag"] = value;
521 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700522 }
523 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +0200524 break;
Ed Tanous6c34de42018-08-29 13:37:36 -0700525 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700526 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700527 },
528 "xyz.openbmc_project.ObjectMapper",
529 "/xyz/openbmc_project/object_mapper",
530 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700531 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500532 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700533 "xyz.openbmc_project.Inventory.Decorator.Asset",
534 "xyz.openbmc_project.Inventory.Item.Cpu",
535 "xyz.openbmc_project.Inventory.Item.Dimm",
536 "xyz.openbmc_project.Inventory.Item.System",
537 "xyz.openbmc_project.Common.UUID",
538 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700539}
540
541/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700542 * @brief Retrieves host state properties over dbus
543 *
544 * @param[in] aResp Shared pointer for completing asynchronous calls.
545 *
546 * @return None.
547 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800548inline void getHostState(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700549{
550 BMCWEB_LOG_DEBUG << "Get host information.";
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700551 sdbusplus::asio::getProperty<std::string>(
552 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
553 "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
554 "CurrentHostState",
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800555 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700556 const std::string& hostState) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700557 if (ec)
558 {
559 if (ec == boost::system::errc::host_unreachable)
Ed Tanous6c34de42018-08-29 13:37:36 -0700560 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700561 // Service not available, no error, just don't return
562 // host state info
563 BMCWEB_LOG_DEBUG << "Service not available " << ec;
Ed Tanous6c34de42018-08-29 13:37:36 -0700564 return;
565 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700566 BMCWEB_LOG_ERROR << "DBUS response error " << ec;
567 messages::internalError(aResp->res);
568 return;
569 }
Ed Tanous66173382018-08-15 18:20:59 -0700570
Ed Tanous002d39b2022-05-31 08:59:27 -0700571 BMCWEB_LOG_DEBUG << "Host state: " << hostState;
572 // Verify Host State
573 if (hostState == "xyz.openbmc_project.State.Host.HostState.Running")
574 {
575 aResp->res.jsonValue["PowerState"] = "On";
576 aResp->res.jsonValue["Status"]["State"] = "Enabled";
577 }
578 else if (hostState ==
579 "xyz.openbmc_project.State.Host.HostState.Quiesced")
580 {
581 aResp->res.jsonValue["PowerState"] = "On";
582 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
583 }
584 else if (hostState ==
585 "xyz.openbmc_project.State.Host.HostState.DiagnosticMode")
586 {
587 aResp->res.jsonValue["PowerState"] = "On";
588 aResp->res.jsonValue["Status"]["State"] = "InTest";
589 }
590 else if (
591 hostState ==
592 "xyz.openbmc_project.State.Host.HostState.TransitioningToRunning")
593 {
594 aResp->res.jsonValue["PowerState"] = "PoweringOn";
595 aResp->res.jsonValue["Status"]["State"] = "Starting";
596 }
597 else if (hostState ==
598 "xyz.openbmc_project.State.Host.HostState.TransitioningToOff")
599 {
600 aResp->res.jsonValue["PowerState"] = "PoweringOff";
601 aResp->res.jsonValue["Status"]["State"] = "Disabled";
602 }
603 else
604 {
605 aResp->res.jsonValue["PowerState"] = "Off";
606 aResp->res.jsonValue["Status"]["State"] = "Disabled";
607 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700608 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700609}
610
611/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500612 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530613 *
614 * @param[in] dbusSource The boot source in DBUS speak.
615 *
616 * @return Returns as a string, the boot source in Redfish terms. If translation
617 * cannot be done, returns an empty string.
618 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000619inline std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530620{
621 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
622 {
623 return "None";
624 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700625 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530626 {
627 return "Hdd";
628 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700629 if (dbusSource ==
630 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530631 {
632 return "Cd";
633 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700634 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530635 {
636 return "Pxe";
637 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700638 if (dbusSource ==
639 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700640 {
641 return "Usb";
642 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700643 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530644}
645
646/**
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300647 * @brief Translates boot type DBUS property value to redfish.
648 *
649 * @param[in] dbusType The boot type in DBUS speak.
650 *
651 * @return Returns as a string, the boot type in Redfish terms. If translation
652 * cannot be done, returns an empty string.
653 */
654inline std::string dbusToRfBootType(const std::string& dbusType)
655{
656 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.Legacy")
657 {
658 return "Legacy";
659 }
660 if (dbusType == "xyz.openbmc_project.Control.Boot.Type.Types.EFI")
661 {
662 return "UEFI";
663 }
664 return "";
665}
666
667/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500668 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530669 *
670 * @param[in] dbusMode The boot mode in DBUS speak.
671 *
672 * @return Returns as a string, the boot mode in Redfish terms. If translation
673 * cannot be done, returns an empty string.
674 */
Ed Tanous23a21a12020-07-25 04:45:05 +0000675inline std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530676{
677 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
678 {
679 return "None";
680 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700681 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682 {
683 return "Diags";
684 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700685 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530686 {
687 return "BiosSetup";
688 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700689 return "";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530690}
691
692/**
Andrew Geisslere43914b2022-01-06 13:59:39 -0600693 * @brief Translates boot progress DBUS property value to redfish.
694 *
695 * @param[in] dbusBootProgress The boot progress in DBUS speak.
696 *
697 * @return Returns as a string, the boot progress in Redfish terms. If
698 * translation cannot be done, returns "None".
699 */
700inline std::string dbusToRfBootProgress(const std::string& dbusBootProgress)
701{
702 // Now convert the D-Bus BootProgress to the appropriate Redfish
703 // enum
704 std::string rfBpLastState = "None";
705 if (dbusBootProgress == "xyz.openbmc_project.State.Boot.Progress."
706 "ProgressStages.Unspecified")
707 {
708 rfBpLastState = "None";
709 }
710 else if (dbusBootProgress ==
711 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
712 "PrimaryProcInit")
713 {
714 rfBpLastState = "PrimaryProcessorInitializationStarted";
715 }
716 else if (dbusBootProgress ==
717 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
718 "BusInit")
719 {
720 rfBpLastState = "BusInitializationStarted";
721 }
722 else if (dbusBootProgress ==
723 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
724 "MemoryInit")
725 {
726 rfBpLastState = "MemoryInitializationStarted";
727 }
728 else if (dbusBootProgress ==
729 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
730 "SecondaryProcInit")
731 {
732 rfBpLastState = "SecondaryProcessorInitializationStarted";
733 }
734 else if (dbusBootProgress ==
735 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
736 "PCIInit")
737 {
738 rfBpLastState = "PCIResourceConfigStarted";
739 }
740 else if (dbusBootProgress ==
741 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
742 "SystemSetup")
743 {
744 rfBpLastState = "SetupEntered";
745 }
746 else if (dbusBootProgress ==
747 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
748 "SystemInitComplete")
749 {
750 rfBpLastState = "SystemHardwareInitializationComplete";
751 }
752 else if (dbusBootProgress ==
753 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
754 "OSStart")
755 {
756 rfBpLastState = "OSBootStarted";
757 }
758 else if (dbusBootProgress ==
759 "xyz.openbmc_project.State.Boot.Progress.ProgressStages."
760 "OSRunning")
761 {
762 rfBpLastState = "OSRunning";
763 }
764 else
765 {
766 BMCWEB_LOG_DEBUG << "Unsupported D-Bus BootProgress "
767 << dbusBootProgress;
768 // Just return the default
769 }
770 return rfBpLastState;
771}
772
773/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500774 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530775 *
776 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700777 * @param[out] bootSource The DBus source
778 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530779 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700780 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530781 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800782inline int assignBootParameters(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500783 const std::string& rfSource,
784 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530785{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300786 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
787 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700788
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530789 if (rfSource == "None")
790 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700791 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530792 }
Ed Tanous3174e4d2020-10-07 11:41:22 -0700793 if (rfSource == "Pxe")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530794 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700795 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
796 }
797 else if (rfSource == "Hdd")
798 {
799 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
800 }
801 else if (rfSource == "Diags")
802 {
803 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
804 }
805 else if (rfSource == "Cd")
806 {
807 bootSource =
808 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
809 }
810 else if (rfSource == "BiosSetup")
811 {
812 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530813 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700814 else if (rfSource == "Usb")
815 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700816 bootSource =
817 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700818 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530819 else
820 {
George Liu0fda0f12021-11-16 10:06:17 +0800821 BMCWEB_LOG_DEBUG
822 << "Invalid property value for BootSourceOverrideTarget: "
823 << bootSource;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700824 messages::propertyValueNotInList(aResp->res, rfSource,
825 "BootSourceTargetOverride");
826 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530827 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700828 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530829}
Ali Ahmed19817712021-06-29 17:01:52 -0500830
Andrew Geissler978b8802020-11-19 13:36:40 -0600831/**
832 * @brief Retrieves boot progress of the system
833 *
834 * @param[in] aResp Shared pointer for generating response message.
835 *
836 * @return None.
837 */
zhanghch058d1b46d2021-04-01 11:18:24 +0800838inline void getBootProgress(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Andrew Geissler978b8802020-11-19 13:36:40 -0600839{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700840 sdbusplus::asio::getProperty<std::string>(
841 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
842 "/xyz/openbmc_project/state/host0",
843 "xyz.openbmc_project.State.Boot.Progress", "BootProgress",
Andrew Geissler978b8802020-11-19 13:36:40 -0600844 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700845 const std::string& bootProgressStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700846 if (ec)
847 {
848 // BootProgress is an optional object so just do nothing if
849 // not found
850 return;
851 }
Andrew Geissler978b8802020-11-19 13:36:40 -0600852
Ed Tanous002d39b2022-05-31 08:59:27 -0700853 BMCWEB_LOG_DEBUG << "Boot Progress: " << bootProgressStr;
Andrew Geissler978b8802020-11-19 13:36:40 -0600854
Ed Tanous002d39b2022-05-31 08:59:27 -0700855 aResp->res.jsonValue["BootProgress"]["LastState"] =
856 dbusToRfBootProgress(bootProgressStr);
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700857 });
Andrew Geissler978b8802020-11-19 13:36:40 -0600858}
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530859
860/**
Hieu Huynhb6d5d452022-10-07 09:41:46 +0000861 * @brief Retrieves boot progress Last Update of the system
862 *
863 * @param[in] aResp Shared pointer for generating response message.
864 *
865 * @return None.
866 */
867inline void getBootProgressLastStateTime(
868 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
869{
870 sdbusplus::asio::getProperty<uint64_t>(
871 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
872 "/xyz/openbmc_project/state/host0",
873 "xyz.openbmc_project.State.Boot.Progress", "BootProgressLastUpdate",
874 [aResp](const boost::system::error_code ec,
875 const uint64_t lastStateTime) {
876 if (ec)
877 {
878 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
879 return;
880 }
881
882 // BootProgressLastUpdate is the last time the BootProgress property
883 // was updated. The time is the Epoch time, number of microseconds
884 // since 1 Jan 1970 00::00::00 UTC."
885 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/
886 // yaml/xyz/openbmc_project/State/Boot/Progress.interface.yaml#L11
887
888 // Convert to ISO 8601 standard
889 aResp->res.jsonValue["BootProgress"]["LastStateTime"] =
890 redfish::time_utils::getDateTimeUintUs(lastStateTime);
891 });
892}
893
894/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300895 * @brief Retrieves boot override type over DBUS and fills out the response
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300896 *
897 * @param[in] aResp Shared pointer for generating response message.
898 *
899 * @return None.
900 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300901
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300902inline void getBootOverrideType(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300903{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700904 sdbusplus::asio::getProperty<std::string>(
905 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
906 "/xyz/openbmc_project/control/host0/boot",
907 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300908 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700909 const std::string& bootType) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700910 if (ec)
911 {
912 // not an error, don't have to have the interface
913 return;
914 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300915
Ed Tanous002d39b2022-05-31 08:59:27 -0700916 BMCWEB_LOG_DEBUG << "Boot type: " << bootType;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300917
Ed Tanous002d39b2022-05-31 08:59:27 -0700918 aResp->res.jsonValue["Boot"]
919 ["BootSourceOverrideMode@Redfish.AllowableValues"] =
Ed Tanous613dabe2022-07-09 11:17:36 -0700920 nlohmann::json::array_t({"Legacy", "UEFI"});
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300921
Ed Tanous002d39b2022-05-31 08:59:27 -0700922 auto rfType = dbusToRfBootType(bootType);
923 if (rfType.empty())
924 {
925 messages::internalError(aResp->res);
926 return;
927 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300928
Ed Tanous002d39b2022-05-31 08:59:27 -0700929 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = rfType;
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700930 });
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +0300931}
932
933/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300934 * @brief Retrieves boot override mode over DBUS and fills out the response
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530935 *
936 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530937 *
938 * @return None.
939 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300940
941inline void getBootOverrideMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530942{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700943 sdbusplus::asio::getProperty<std::string>(
944 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
945 "/xyz/openbmc_project/control/host0/boot",
946 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300947 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700948 const std::string& bootModeStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700949 if (ec)
950 {
951 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
952 messages::internalError(aResp->res);
953 return;
954 }
955
956 BMCWEB_LOG_DEBUG << "Boot mode: " << bootModeStr;
957
958 aResp->res
959 .jsonValue["Boot"]
960 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
961 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
962
963 if (bootModeStr !=
964 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
965 {
966 auto rfMode = dbusToRfBootMode(bootModeStr);
967 if (!rfMode.empty())
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530968 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700969 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
970 rfMode;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530971 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700972 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700973 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974}
975
976/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300977 * @brief Retrieves boot override source over DBUS
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530978 *
979 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530980 *
981 * @return None.
982 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300983
984inline void
985 getBootOverrideSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530986{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700987 sdbusplus::asio::getProperty<std::string>(
988 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
989 "/xyz/openbmc_project/control/host0/boot",
990 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +0300991 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700992 const std::string& bootSourceStr) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700993 if (ec)
994 {
995 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +0000996 if (ec.value() == boost::asio::error::host_unreachable)
997 {
998 return;
999 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001000 messages::internalError(aResp->res);
1001 return;
1002 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301003
Ed Tanous002d39b2022-05-31 08:59:27 -07001004 BMCWEB_LOG_DEBUG << "Boot source: " << bootSourceStr;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301005
Ed Tanous002d39b2022-05-31 08:59:27 -07001006 auto rfSource = dbusToRfBootSource(bootSourceStr);
1007 if (!rfSource.empty())
1008 {
1009 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] = rfSource;
1010 }
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001011
Ed Tanous002d39b2022-05-31 08:59:27 -07001012 // Get BootMode as BootSourceOverrideTarget is constructed
1013 // from both BootSource and BootMode
1014 getBootOverrideMode(aResp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001015 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301016}
1017
1018/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001019 * @brief This functions abstracts all the logic behind getting a
1020 * "BootSourceOverrideEnabled" property from an overall boot override enable
1021 * state
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301022 *
1023 * @param[in] aResp Shared pointer for generating response message.
1024 *
1025 * @return None.
1026 */
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301027
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001028inline void
1029 processBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1030 const bool bootOverrideEnableSetting)
1031{
1032 if (!bootOverrideEnableSetting)
1033 {
1034 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Disabled";
1035 return;
1036 }
1037
1038 // If boot source override is enabled, we need to check 'one_time'
1039 // property to set a correct value for the "BootSourceOverrideEnabled"
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001040 sdbusplus::asio::getProperty<bool>(
1041 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1042 "/xyz/openbmc_project/control/host0/boot/one_time",
1043 "xyz.openbmc_project.Object.Enable", "Enabled",
1044 [aResp](const boost::system::error_code ec, bool oneTimeSetting) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001045 if (ec)
1046 {
1047 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1048 messages::internalError(aResp->res);
1049 return;
1050 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301051
Ed Tanous002d39b2022-05-31 08:59:27 -07001052 if (oneTimeSetting)
1053 {
1054 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] = "Once";
1055 }
1056 else
1057 {
1058 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
1059 "Continuous";
1060 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001061 });
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301062}
1063
1064/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001065 * @brief Retrieves boot override enable over DBUS
1066 *
1067 * @param[in] aResp Shared pointer for generating response message.
1068 *
1069 * @return None.
1070 */
1071
1072inline void
1073 getBootOverrideEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1074{
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001075 sdbusplus::asio::getProperty<bool>(
1076 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1077 "/xyz/openbmc_project/control/host0/boot",
1078 "xyz.openbmc_project.Object.Enable", "Enabled",
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001079 [aResp](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001080 const bool bootOverrideEnable) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001081 if (ec)
1082 {
1083 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Nan Zhou5ef735c2022-06-22 05:24:21 +00001084 if (ec.value() == boost::asio::error::host_unreachable)
1085 {
1086 return;
1087 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001088 messages::internalError(aResp->res);
1089 return;
1090 }
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001091
Ed Tanous002d39b2022-05-31 08:59:27 -07001092 processBootOverrideEnable(aResp, bootOverrideEnable);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001093 });
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001094}
1095
1096/**
1097 * @brief Retrieves boot source override properties
1098 *
1099 * @param[in] aResp Shared pointer for generating response message.
1100 *
1101 * @return None.
1102 */
1103inline void getBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1104{
1105 BMCWEB_LOG_DEBUG << "Get boot information.";
1106
1107 getBootOverrideSource(aResp);
1108 getBootOverrideType(aResp);
1109 getBootOverrideEnable(aResp);
1110}
1111
1112/**
Gunnar Millsc0557e12020-06-30 11:26:20 -05001113 * @brief Retrieves the Last Reset Time
1114 *
1115 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
1116 * and power off. Even though this is the "system" Redfish object look at the
1117 * chassis D-Bus interface for the LastStateChangeTime since this has the
1118 * last power operation time.
1119 *
1120 * @param[in] aResp Shared pointer for generating response message.
1121 *
1122 * @return None.
1123 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001124inline void getLastResetTime(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Millsc0557e12020-06-30 11:26:20 -05001125{
1126 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
1127
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001128 sdbusplus::asio::getProperty<uint64_t>(
1129 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
1130 "/xyz/openbmc_project/state/chassis0",
1131 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime",
1132 [aResp](const boost::system::error_code ec, uint64_t lastResetTime) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001133 if (ec)
1134 {
1135 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1136 return;
1137 }
Gunnar Millsc0557e12020-06-30 11:26:20 -05001138
Ed Tanous002d39b2022-05-31 08:59:27 -07001139 // LastStateChangeTime is epoch time, in milliseconds
1140 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
1141 uint64_t lastResetTimeStamp = lastResetTime / 1000;
Gunnar Millsc0557e12020-06-30 11:26:20 -05001142
Ed Tanous002d39b2022-05-31 08:59:27 -07001143 // Convert to ISO 8601 standard
1144 aResp->res.jsonValue["LastResetTime"] =
Ed Tanous2b829372022-08-03 14:22:34 -07001145 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001146 });
Gunnar Millsc0557e12020-06-30 11:26:20 -05001147}
1148
1149/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001150 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
1151 *
1152 * @param[in] aResp Shared pointer for generating response message.
1153 *
1154 * @return None.
1155 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001156inline void getAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001157{
1158 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
1159
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001160 sdbusplus::asio::getProperty<bool>(
1161 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1162 "/xyz/openbmc_project/control/host0/auto_reboot",
1163 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1164 [aResp](const boost::system::error_code ec, bool autoRebootEnabled) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001165 if (ec)
1166 {
1167 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1168 return;
1169 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001170
Ed Tanous002d39b2022-05-31 08:59:27 -07001171 BMCWEB_LOG_DEBUG << "Auto Reboot: " << autoRebootEnabled;
1172 if (autoRebootEnabled)
1173 {
1174 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1175 "RetryAttempts";
1176 // If AutomaticRetry (AutoReboot) is enabled see how many
1177 // attempts are left
1178 sdbusplus::asio::getProperty<uint32_t>(
1179 *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
1180 "/xyz/openbmc_project/state/host0",
1181 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1182 "AttemptsLeft",
1183 [aResp](const boost::system::error_code ec2,
1184 const uint32_t autoRebootAttemptsLeft) {
1185 if (ec2)
1186 {
1187 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec2;
1188 return;
1189 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001190
Ed Tanous002d39b2022-05-31 08:59:27 -07001191 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1192 << autoRebootAttemptsLeft;
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001193
Ed Tanous002d39b2022-05-31 08:59:27 -07001194 aResp->res
1195 .jsonValue["Boot"]["RemainingAutomaticRetryAttempts"] =
1196 autoRebootAttemptsLeft;
1197 });
1198 }
1199 else
1200 {
1201 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] = "Disabled";
1202 }
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001203
Ed Tanous002d39b2022-05-31 08:59:27 -07001204 // Not on D-Bus. Hardcoded here:
1205 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1206 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001207
Ed Tanous002d39b2022-05-31 08:59:27 -07001208 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1209 // and RetryAttempts. OpenBMC only supports Disabled and
1210 // RetryAttempts.
1211 aResp->res.jsonValue["Boot"]
1212 ["AutomaticRetryConfig@Redfish.AllowableValues"] = {
1213 "Disabled", "RetryAttempts"};
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001214 });
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001215}
1216
1217/**
George Liuc6a620f2020-04-10 17:18:11 +08001218 * @brief Retrieves power restore policy over DBUS.
1219 *
1220 * @param[in] aResp Shared pointer for generating response message.
1221 *
1222 * @return None.
1223 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001224inline void
1225 getPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
George Liuc6a620f2020-04-10 17:18:11 +08001226{
1227 BMCWEB_LOG_DEBUG << "Get power restore policy";
1228
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001229 sdbusplus::asio::getProperty<std::string>(
1230 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
1231 "/xyz/openbmc_project/control/host0/power_restore_policy",
1232 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1233 [aResp](const boost::system::error_code ec, const std::string& policy) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001234 if (ec)
1235 {
1236 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1237 return;
1238 }
George Liuc6a620f2020-04-10 17:18:11 +08001239
Ed Tanous002d39b2022-05-31 08:59:27 -07001240 const boost::container::flat_map<std::string, std::string> policyMaps = {
1241 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn",
1242 "AlwaysOn"},
1243 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff",
1244 "AlwaysOff"},
1245 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore",
1246 "LastState"},
1247 // Return `AlwaysOff` when power restore policy set to "None"
1248 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy.None",
1249 "AlwaysOff"}};
George Liuc6a620f2020-04-10 17:18:11 +08001250
Ed Tanous002d39b2022-05-31 08:59:27 -07001251 auto policyMapsIt = policyMaps.find(policy);
1252 if (policyMapsIt == policyMaps.end())
1253 {
1254 messages::internalError(aResp->res);
1255 return;
1256 }
George Liuc6a620f2020-04-10 17:18:11 +08001257
Ed Tanous002d39b2022-05-31 08:59:27 -07001258 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
Jonathan Doman1e1e5982021-06-11 09:36:17 -07001259 });
George Liuc6a620f2020-04-10 17:18:11 +08001260}
1261
1262/**
Ali Ahmed19817712021-06-29 17:01:52 -05001263 * @brief Get TrustedModuleRequiredToBoot property. Determines whether or not
1264 * TPM is required for booting the host.
1265 *
1266 * @param[in] aResp Shared pointer for generating response message.
1267 *
1268 * @return None.
1269 */
1270inline void getTrustedModuleRequiredToBoot(
1271 const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1272{
1273 BMCWEB_LOG_DEBUG << "Get TPM required to boot.";
1274
1275 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001276 [aResp](const boost::system::error_code ec,
1277 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001278 if (ec)
1279 {
1280 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1281 << ec;
1282 // This is an optional D-Bus object so just return if
1283 // error occurs
1284 return;
1285 }
1286 if (subtree.empty())
1287 {
1288 // As noted above, this is an optional interface so just return
1289 // if there is no instance found
1290 return;
1291 }
1292
1293 /* When there is more than one TPMEnable object... */
1294 if (subtree.size() > 1)
1295 {
1296 BMCWEB_LOG_DEBUG
1297 << "DBUS response has more than 1 TPM Enable object:"
1298 << subtree.size();
1299 // Throw an internal Error and return
1300 messages::internalError(aResp->res);
1301 return;
1302 }
1303
1304 // Make sure the Dbus response map has a service and objectPath
1305 // field
1306 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1307 {
1308 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1309 messages::internalError(aResp->res);
1310 return;
1311 }
1312
1313 const std::string& path = subtree[0].first;
1314 const std::string& serv = subtree[0].second.begin()->first;
1315
1316 // Valid TPM Enable object found, now reading the current value
1317 sdbusplus::asio::getProperty<bool>(
1318 *crow::connections::systemBus, serv, path,
1319 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
Ed Tanous8a592812022-06-04 09:06:59 -07001320 [aResp](const boost::system::error_code ec2, bool tpmRequired) {
1321 if (ec2)
Ali Ahmed19817712021-06-29 17:01:52 -05001322 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001323 BMCWEB_LOG_DEBUG << "D-BUS response error on TPM.Policy Get"
Ed Tanous8a592812022-06-04 09:06:59 -07001324 << ec2;
Ali Ahmed19817712021-06-29 17:01:52 -05001325 messages::internalError(aResp->res);
1326 return;
1327 }
1328
Ed Tanous002d39b2022-05-31 08:59:27 -07001329 if (tpmRequired)
Ali Ahmed19817712021-06-29 17:01:52 -05001330 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001331 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1332 "Required";
Ali Ahmed19817712021-06-29 17:01:52 -05001333 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001334 else
1335 {
1336 aResp->res.jsonValue["Boot"]["TrustedModuleRequiredToBoot"] =
1337 "Disabled";
1338 }
1339 });
Ali Ahmed19817712021-06-29 17:01:52 -05001340 },
1341 "xyz.openbmc_project.ObjectMapper",
1342 "/xyz/openbmc_project/object_mapper",
1343 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1344 std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1345}
1346
1347/**
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001348 * @brief Set TrustedModuleRequiredToBoot property. Determines whether or not
1349 * TPM is required for booting the host.
1350 *
1351 * @param[in] aResp Shared pointer for generating response message.
1352 * @param[in] tpmRequired Value to set TPM Required To Boot property to.
1353 *
1354 * @return None.
1355 */
1356inline void setTrustedModuleRequiredToBoot(
1357 const std::shared_ptr<bmcweb::AsyncResp>& aResp, const bool tpmRequired)
1358{
1359 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot.";
1360
1361 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001362 [aResp, tpmRequired](const boost::system::error_code ec,
1363 dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001364 if (ec)
1365 {
1366 BMCWEB_LOG_DEBUG << "DBUS response error on TPM.Policy GetSubTree"
1367 << ec;
1368 messages::internalError(aResp->res);
1369 return;
1370 }
1371 if (subtree.empty())
1372 {
1373 messages::propertyValueNotInList(aResp->res, "ComputerSystem",
1374 "TrustedModuleRequiredToBoot");
1375 return;
1376 }
1377
1378 /* When there is more than one TPMEnable object... */
1379 if (subtree.size() > 1)
1380 {
1381 BMCWEB_LOG_DEBUG
1382 << "DBUS response has more than 1 TPM Enable object:"
1383 << subtree.size();
1384 // Throw an internal Error and return
1385 messages::internalError(aResp->res);
1386 return;
1387 }
1388
1389 // Make sure the Dbus response map has a service and objectPath
1390 // field
1391 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1392 {
1393 BMCWEB_LOG_DEBUG << "TPM.Policy mapper error!";
1394 messages::internalError(aResp->res);
1395 return;
1396 }
1397
1398 const std::string& path = subtree[0].first;
1399 const std::string& serv = subtree[0].second.begin()->first;
1400
1401 if (serv.empty())
1402 {
1403 BMCWEB_LOG_DEBUG << "TPM.Policy service mapper error!";
1404 messages::internalError(aResp->res);
1405 return;
1406 }
1407
1408 // Valid TPM Enable object found, now setting the value
1409 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07001410 [aResp](const boost::system::error_code ec2) {
1411 if (ec2)
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001412 {
1413 BMCWEB_LOG_DEBUG
Ed Tanous002d39b2022-05-31 08:59:27 -07001414 << "DBUS response error: Set TrustedModuleRequiredToBoot"
Ed Tanous8a592812022-06-04 09:06:59 -07001415 << ec2;
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001416 messages::internalError(aResp->res);
1417 return;
1418 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001419 BMCWEB_LOG_DEBUG << "Set TrustedModuleRequiredToBoot done.";
1420 },
1421 serv, path, "org.freedesktop.DBus.Properties", "Set",
1422 "xyz.openbmc_project.Control.TPM.Policy", "TPMEnable",
1423 dbus::utility::DbusVariantType(tpmRequired));
Ali Ahmed1c05dae2021-06-29 17:49:22 -05001424 },
1425 "xyz.openbmc_project.ObjectMapper",
1426 "/xyz/openbmc_project/object_mapper",
1427 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
1428 std::array<const char*, 1>{"xyz.openbmc_project.Control.TPM.Policy"});
1429}
1430
1431/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301432 * @brief Sets boot properties into DBUS object(s).
1433 *
1434 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001435 * @param[in] bootType The boot type to set.
1436 * @return Integer error code.
1437 */
1438inline void setBootType(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001439 const std::optional<std::string>& bootType)
1440{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001441 std::string bootTypeStr;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001442
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001443 if (!bootType)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001444 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001445 return;
1446 }
1447
1448 // Source target specified
1449 BMCWEB_LOG_DEBUG << "Boot type: " << *bootType;
1450 // Figure out which DBUS interface and property to use
1451 if (*bootType == "Legacy")
1452 {
1453 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.Legacy";
1454 }
1455 else if (*bootType == "UEFI")
1456 {
1457 bootTypeStr = "xyz.openbmc_project.Control.Boot.Type.Types.EFI";
1458 }
1459 else
1460 {
1461 BMCWEB_LOG_DEBUG << "Invalid property value for "
1462 "BootSourceOverrideMode: "
1463 << *bootType;
1464 messages::propertyValueNotInList(aResp->res, *bootType,
1465 "BootSourceOverrideMode");
1466 return;
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001467 }
1468
1469 // Act on validated parameters
1470 BMCWEB_LOG_DEBUG << "DBUS boot type: " << bootTypeStr;
1471
1472 crow::connections::systemBus->async_method_call(
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001473 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001474 if (ec)
1475 {
1476 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1477 if (ec.value() == boost::asio::error::host_unreachable)
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001478 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001479 messages::resourceNotFound(aResp->res, "Set", "BootType");
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001480 return;
1481 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001482 messages::internalError(aResp->res);
1483 return;
1484 }
1485 BMCWEB_LOG_DEBUG << "Boot type update done.";
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001486 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001487 "xyz.openbmc_project.Settings",
1488 "/xyz/openbmc_project/control/host0/boot",
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001489 "org.freedesktop.DBus.Properties", "Set",
1490 "xyz.openbmc_project.Control.Boot.Type", "BootType",
Ed Tanous168e20c2021-12-13 14:39:53 -08001491 dbus::utility::DbusVariantType(bootTypeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001492}
1493
1494/**
1495 * @brief Sets boot properties into DBUS object(s).
1496 *
1497 * @param[in] aResp Shared pointer for generating response message.
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001498 * @param[in] bootType The boot type to set.
1499 * @return Integer error code.
1500 */
1501inline void setBootEnable(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1502 const std::optional<std::string>& bootEnable)
1503{
1504 if (!bootEnable)
1505 {
1506 return;
1507 }
1508 // Source target specified
1509 BMCWEB_LOG_DEBUG << "Boot enable: " << *bootEnable;
1510
1511 bool bootOverrideEnable = false;
1512 bool bootOverridePersistent = false;
1513 // Figure out which DBUS interface and property to use
1514 if (*bootEnable == "Disabled")
1515 {
1516 bootOverrideEnable = false;
1517 }
1518 else if (*bootEnable == "Once")
1519 {
1520 bootOverrideEnable = true;
1521 bootOverridePersistent = false;
1522 }
1523 else if (*bootEnable == "Continuous")
1524 {
1525 bootOverrideEnable = true;
1526 bootOverridePersistent = true;
1527 }
1528 else
1529 {
George Liu0fda0f12021-11-16 10:06:17 +08001530 BMCWEB_LOG_DEBUG
1531 << "Invalid property value for BootSourceOverrideEnabled: "
1532 << *bootEnable;
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001533 messages::propertyValueNotInList(aResp->res, *bootEnable,
1534 "BootSourceOverrideEnabled");
1535 return;
1536 }
1537
1538 // Act on validated parameters
1539 BMCWEB_LOG_DEBUG << "DBUS boot override enable: " << bootOverrideEnable;
1540
1541 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07001542 [aResp](const boost::system::error_code ec2) {
1543 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07001544 {
Ed Tanous8a592812022-06-04 09:06:59 -07001545 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07001546 messages::internalError(aResp->res);
1547 return;
1548 }
1549 BMCWEB_LOG_DEBUG << "Boot override enable update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001550 },
1551 "xyz.openbmc_project.Settings",
1552 "/xyz/openbmc_project/control/host0/boot",
1553 "org.freedesktop.DBus.Properties", "Set",
1554 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001555 dbus::utility::DbusVariantType(bootOverrideEnable));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001556
1557 if (!bootOverrideEnable)
1558 {
1559 return;
1560 }
1561
1562 // In case boot override is enabled we need to set correct value for the
1563 // 'one_time' enable DBus interface
1564 BMCWEB_LOG_DEBUG << "DBUS boot override persistent: "
1565 << bootOverridePersistent;
1566
1567 crow::connections::systemBus->async_method_call(
1568 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001569 if (ec)
1570 {
1571 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1572 messages::internalError(aResp->res);
1573 return;
1574 }
1575 BMCWEB_LOG_DEBUG << "Boot one_time update done.";
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001576 },
1577 "xyz.openbmc_project.Settings",
1578 "/xyz/openbmc_project/control/host0/boot/one_time",
1579 "org.freedesktop.DBus.Properties", "Set",
1580 "xyz.openbmc_project.Object.Enable", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08001581 dbus::utility::DbusVariantType(!bootOverridePersistent));
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001582}
1583
1584/**
1585 * @brief Sets boot properties into DBUS object(s).
1586 *
1587 * @param[in] aResp Shared pointer for generating response message.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301588 * @param[in] bootSource The boot source to set.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301589 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001590 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301591 */
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001592inline void setBootModeOrSource(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001593 const std::optional<std::string>& bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301594{
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001595 std::string bootSourceStr;
1596 std::string bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001597
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001598 if (!bootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301599 {
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001600 return;
1601 }
1602
1603 // Source target specified
1604 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1605 // Figure out which DBUS interface and property to use
Ed Tanouse662eae2022-01-25 10:39:19 -08001606 if (assignBootParameters(aResp, *bootSource, bootSourceStr, bootModeStr) !=
1607 0)
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001608 {
1609 BMCWEB_LOG_DEBUG
1610 << "Invalid property value for BootSourceOverrideTarget: "
1611 << *bootSource;
1612 messages::propertyValueNotInList(aResp->res, *bootSource,
1613 "BootSourceTargetOverride");
1614 return;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001615 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301616
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001617 // Act on validated parameters
1618 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1619 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001620
1621 crow::connections::systemBus->async_method_call(
1622 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001623 if (ec)
1624 {
1625 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1626 messages::internalError(aResp->res);
1627 return;
1628 }
1629 BMCWEB_LOG_DEBUG << "Boot source update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001630 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001631 "xyz.openbmc_project.Settings",
1632 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001633 "org.freedesktop.DBus.Properties", "Set",
1634 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
Ed Tanous168e20c2021-12-13 14:39:53 -08001635 dbus::utility::DbusVariantType(bootSourceStr));
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001636
1637 crow::connections::systemBus->async_method_call(
1638 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001639 if (ec)
1640 {
1641 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1642 messages::internalError(aResp->res);
1643 return;
1644 }
1645 BMCWEB_LOG_DEBUG << "Boot mode update done.";
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001646 },
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001647 "xyz.openbmc_project.Settings",
1648 "/xyz/openbmc_project/control/host0/boot",
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001649 "org.freedesktop.DBus.Properties", "Set",
1650 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
Ed Tanous168e20c2021-12-13 14:39:53 -08001651 dbus::utility::DbusVariantType(bootModeStr));
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001652}
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001653
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001654/**
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001655 * @brief Sets Boot source override properties.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301656 *
1657 * @param[in] aResp Shared pointer for generating response message.
1658 * @param[in] bootSource The boot source from incoming RF request.
Konstantin Aladyshevcd9a4662021-02-26 12:37:07 +03001659 * @param[in] bootType The boot type from incoming RF request.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301660 * @param[in] bootEnable The boot override enable from incoming RF request.
1661 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001662 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301663 */
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001664
1665inline void setBootProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1666 const std::optional<std::string>& bootSource,
1667 const std::optional<std::string>& bootType,
1668 const std::optional<std::string>& bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301669{
1670 BMCWEB_LOG_DEBUG << "Set boot information.";
1671
Konstantin Aladyshevc21865c2021-06-21 14:49:16 +03001672 setBootModeOrSource(aResp, bootSource);
1673 setBootType(aResp, bootType);
1674 setBootEnable(aResp, bootEnable);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301675}
1676
George Liuc6a620f2020-04-10 17:18:11 +08001677/**
Gunnar Mills98e386e2020-10-30 14:58:09 -05001678 * @brief Sets AssetTag
1679 *
1680 * @param[in] aResp Shared pointer for generating response message.
1681 * @param[in] assetTag "AssetTag" from request.
1682 *
1683 * @return None.
1684 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001685inline void setAssetTag(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Gunnar Mills98e386e2020-10-30 14:58:09 -05001686 const std::string& assetTag)
1687{
1688 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001689 [aResp,
1690 assetTag](const boost::system::error_code ec,
1691 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001692 if (ec)
1693 {
1694 BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
1695 messages::internalError(aResp->res);
1696 return;
1697 }
1698 if (subtree.empty())
1699 {
1700 BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
1701 messages::internalError(aResp->res);
1702 return;
1703 }
1704 // Assume only 1 system D-Bus object
1705 // Throw an error if there is more than 1
1706 if (subtree.size() > 1)
1707 {
1708 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
1709 messages::internalError(aResp->res);
1710 return;
1711 }
1712 if (subtree[0].first.empty() || subtree[0].second.size() != 1)
1713 {
1714 BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
1715 messages::internalError(aResp->res);
1716 return;
1717 }
Gunnar Mills98e386e2020-10-30 14:58:09 -05001718
Ed Tanous002d39b2022-05-31 08:59:27 -07001719 const std::string& path = subtree[0].first;
1720 const std::string& service = subtree[0].second.begin()->first;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001721
Ed Tanous002d39b2022-05-31 08:59:27 -07001722 if (service.empty())
1723 {
1724 BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
1725 messages::internalError(aResp->res);
1726 return;
1727 }
1728
1729 crow::connections::systemBus->async_method_call(
1730 [aResp](const boost::system::error_code ec2) {
1731 if (ec2)
Gunnar Mills98e386e2020-10-30 14:58:09 -05001732 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001733 BMCWEB_LOG_DEBUG << "D-Bus response error on AssetTag Set "
1734 << ec2;
Gunnar Mills98e386e2020-10-30 14:58:09 -05001735 messages::internalError(aResp->res);
1736 return;
1737 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001738 },
1739 service, path, "org.freedesktop.DBus.Properties", "Set",
1740 "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
1741 dbus::utility::DbusVariantType(assetTag));
Gunnar Mills98e386e2020-10-30 14:58:09 -05001742 },
1743 "xyz.openbmc_project.ObjectMapper",
1744 "/xyz/openbmc_project/object_mapper",
1745 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
1746 "/xyz/openbmc_project/inventory", int32_t(0),
1747 std::array<const char*, 1>{
1748 "xyz.openbmc_project.Inventory.Item.System"});
1749}
1750
1751/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001752 * @brief Sets automaticRetry (Auto Reboot)
1753 *
1754 * @param[in] aResp Shared pointer for generating response message.
1755 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1756 *
1757 * @return None.
1758 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001759inline void setAutomaticRetry(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Ed Tanousf23b7292020-10-15 09:41:17 -07001760 const std::string& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001761{
1762 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1763
1764 // OpenBMC only supports "Disabled" and "RetryAttempts".
Ed Tanous543f4402022-01-06 13:12:53 -08001765 bool autoRebootEnabled = false;
Gunnar Mills69f35302020-05-17 16:06:31 -05001766
1767 if (automaticRetryConfig == "Disabled")
1768 {
1769 autoRebootEnabled = false;
1770 }
1771 else if (automaticRetryConfig == "RetryAttempts")
1772 {
1773 autoRebootEnabled = true;
1774 }
1775 else
1776 {
George Liu0fda0f12021-11-16 10:06:17 +08001777 BMCWEB_LOG_DEBUG << "Invalid property value for AutomaticRetryConfig: "
Gunnar Mills69f35302020-05-17 16:06:31 -05001778 << automaticRetryConfig;
1779 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1780 "AutomaticRetryConfig");
1781 return;
1782 }
1783
1784 crow::connections::systemBus->async_method_call(
1785 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001786 if (ec)
1787 {
1788 messages::internalError(aResp->res);
1789 return;
1790 }
Gunnar Mills69f35302020-05-17 16:06:31 -05001791 },
1792 "xyz.openbmc_project.Settings",
1793 "/xyz/openbmc_project/control/host0/auto_reboot",
1794 "org.freedesktop.DBus.Properties", "Set",
1795 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
Ed Tanous168e20c2021-12-13 14:39:53 -08001796 dbus::utility::DbusVariantType(autoRebootEnabled));
Gunnar Mills69f35302020-05-17 16:06:31 -05001797}
1798
1799/**
George Liuc6a620f2020-04-10 17:18:11 +08001800 * @brief Sets power restore policy properties.
1801 *
1802 * @param[in] aResp Shared pointer for generating response message.
1803 * @param[in] policy power restore policy properties from request.
1804 *
1805 * @return None.
1806 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001807inline void
1808 setPowerRestorePolicy(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1809 const std::string& policy)
George Liuc6a620f2020-04-10 17:18:11 +08001810{
1811 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1812
1813 const boost::container::flat_map<std::string, std::string> policyMaps = {
George Liu0fda0f12021-11-16 10:06:17 +08001814 {"AlwaysOn",
1815 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOn"},
1816 {"AlwaysOff",
1817 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.AlwaysOff"},
1818 {"LastState",
1819 "xyz.openbmc_project.Control.Power.RestorePolicy.Policy.Restore"}};
George Liuc6a620f2020-04-10 17:18:11 +08001820
1821 std::string powerRestorPolicy;
1822
Gunnar Mills4e69c902021-01-05 19:50:11 -06001823 auto policyMapsIt = policyMaps.find(policy);
George Liuc6a620f2020-04-10 17:18:11 +08001824 if (policyMapsIt == policyMaps.end())
1825 {
Gunnar Mills4e69c902021-01-05 19:50:11 -06001826 messages::propertyValueNotInList(aResp->res, policy,
1827 "PowerRestorePolicy");
George Liuc6a620f2020-04-10 17:18:11 +08001828 return;
1829 }
1830
1831 powerRestorPolicy = policyMapsIt->second;
1832
1833 crow::connections::systemBus->async_method_call(
1834 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001835 if (ec)
1836 {
1837 messages::internalError(aResp->res);
1838 return;
1839 }
George Liuc6a620f2020-04-10 17:18:11 +08001840 },
1841 "xyz.openbmc_project.Settings",
1842 "/xyz/openbmc_project/control/host0/power_restore_policy",
1843 "org.freedesktop.DBus.Properties", "Set",
1844 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
Ed Tanous168e20c2021-12-13 14:39:53 -08001845 dbus::utility::DbusVariantType(powerRestorPolicy));
George Liuc6a620f2020-04-10 17:18:11 +08001846}
1847
AppaRao Pulia6349912019-10-18 17:16:08 +05301848#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1849/**
1850 * @brief Retrieves provisioning status
1851 *
1852 * @param[in] aResp Shared pointer for completing asynchronous calls.
1853 *
1854 * @return None.
1855 */
zhanghch058d1b46d2021-04-01 11:18:24 +08001856inline void getProvisioningStatus(std::shared_ptr<bmcweb::AsyncResp> aResp)
AppaRao Pulia6349912019-10-18 17:16:08 +05301857{
1858 BMCWEB_LOG_DEBUG << "Get OEM information.";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001859 sdbusplus::asio::getAllProperties(
1860 *crow::connections::systemBus, "xyz.openbmc_project.PFR.Manager",
1861 "/xyz/openbmc_project/pfr", "xyz.openbmc_project.PFR.Attributes",
AppaRao Pulia6349912019-10-18 17:16:08 +05301862 [aResp](const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08001863 const dbus::utility::DBusPropertiesMap& propertiesList) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001864 nlohmann::json& oemPFR =
1865 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1866 aResp->res.jsonValue["Oem"]["OpenBmc"]["@odata.type"] =
1867 "#OemComputerSystem.OpenBmc";
1868 oemPFR["@odata.type"] = "#OemComputerSystem.FirmwareProvisioning";
James Feist50626f42020-09-23 14:40:47 -07001869
Ed Tanous002d39b2022-05-31 08:59:27 -07001870 if (ec)
1871 {
1872 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1873 // not an error, don't have to have the interface
1874 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1875 return;
1876 }
1877
1878 const bool* provState = nullptr;
1879 const bool* lockState = nullptr;
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001880
1881 const bool success = sdbusplus::unpackPropertiesNoThrow(
Jiaqing Zhao0d4befa2022-08-19 15:14:32 +08001882 dbus_utils::UnpackErrorPrinter(), propertiesList, "UfmProvisioned",
1883 provState, "UfmLocked", lockState);
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001884
1885 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07001886 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001887 messages::internalError(aResp->res);
1888 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07001889 }
AppaRao Pulia6349912019-10-18 17:16:08 +05301890
Ed Tanous002d39b2022-05-31 08:59:27 -07001891 if ((provState == nullptr) || (lockState == nullptr))
1892 {
1893 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1894 messages::internalError(aResp->res);
1895 return;
1896 }
AppaRao Pulia6349912019-10-18 17:16:08 +05301897
Ed Tanous002d39b2022-05-31 08:59:27 -07001898 if (*provState == true)
1899 {
1900 if (*lockState == true)
AppaRao Pulia6349912019-10-18 17:16:08 +05301901 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001902 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05301903 }
1904 else
1905 {
Ed Tanous002d39b2022-05-31 08:59:27 -07001906 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
AppaRao Pulia6349912019-10-18 17:16:08 +05301907 }
Ed Tanous002d39b2022-05-31 08:59:27 -07001908 }
1909 else
1910 {
1911 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1912 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02001913 });
AppaRao Pulia6349912019-10-18 17:16:08 +05301914}
1915#endif
1916
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301917/**
Chris Cain3a2d04242021-05-28 16:57:10 -05001918 * @brief Translate the PowerMode to a response message.
1919 *
1920 * @param[in] aResp Shared pointer for generating response message.
1921 * @param[in] modeValue PowerMode value to be translated
1922 *
1923 * @return None.
1924 */
1925inline void translatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1926 const std::string& modeValue)
1927{
George Liu0fda0f12021-11-16 10:06:17 +08001928 if (modeValue == "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static")
Chris Cain3a2d04242021-05-28 16:57:10 -05001929 {
1930 aResp->res.jsonValue["PowerMode"] = "Static";
1931 }
George Liu0fda0f12021-11-16 10:06:17 +08001932 else if (
1933 modeValue ==
1934 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance")
Chris Cain3a2d04242021-05-28 16:57:10 -05001935 {
1936 aResp->res.jsonValue["PowerMode"] = "MaximumPerformance";
1937 }
George Liu0fda0f12021-11-16 10:06:17 +08001938 else if (modeValue ==
1939 "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving")
Chris Cain3a2d04242021-05-28 16:57:10 -05001940 {
1941 aResp->res.jsonValue["PowerMode"] = "PowerSaving";
1942 }
George Liu0fda0f12021-11-16 10:06:17 +08001943 else if (modeValue ==
1944 "xyz.openbmc_project.Control.Power.Mode.PowerMode.OEM")
Chris Cain3a2d04242021-05-28 16:57:10 -05001945 {
1946 aResp->res.jsonValue["PowerMode"] = "OEM";
1947 }
1948 else
1949 {
1950 // Any other values would be invalid
1951 BMCWEB_LOG_DEBUG << "PowerMode value was not valid: " << modeValue;
1952 messages::internalError(aResp->res);
1953 }
1954}
1955
1956/**
1957 * @brief Retrieves system power mode
1958 *
1959 * @param[in] aResp Shared pointer for generating response message.
1960 *
1961 * @return None.
1962 */
1963inline void getPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
1964{
1965 BMCWEB_LOG_DEBUG << "Get power mode.";
1966
1967 // Get Power Mode object path:
1968 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08001969 [aResp](const boost::system::error_code ec,
1970 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07001971 if (ec)
1972 {
1973 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
1974 << ec;
1975 // This is an optional D-Bus object so just return if
1976 // error occurs
1977 return;
1978 }
1979 if (subtree.empty())
1980 {
1981 // As noted above, this is an optional interface so just return
1982 // if there is no instance found
1983 return;
1984 }
1985 if (subtree.size() > 1)
1986 {
1987 // More then one PowerMode object is not supported and is an
1988 // error
1989 BMCWEB_LOG_DEBUG
1990 << "Found more than 1 system D-Bus Power.Mode objects: "
1991 << subtree.size();
1992 messages::internalError(aResp->res);
1993 return;
1994 }
1995 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
1996 {
1997 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
1998 messages::internalError(aResp->res);
1999 return;
2000 }
2001 const std::string& path = subtree[0].first;
2002 const std::string& service = subtree[0].second.begin()->first;
2003 if (service.empty())
2004 {
2005 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2006 messages::internalError(aResp->res);
2007 return;
2008 }
2009 // Valid Power Mode object found, now read the current value
2010 sdbusplus::asio::getProperty<std::string>(
2011 *crow::connections::systemBus, service, path,
2012 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
Ed Tanous8a592812022-06-04 09:06:59 -07002013 [aResp](const boost::system::error_code ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002014 const std::string& pmode) {
Ed Tanous8a592812022-06-04 09:06:59 -07002015 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002016 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002017 BMCWEB_LOG_DEBUG << "DBUS response error on PowerMode Get: "
Ed Tanous8a592812022-06-04 09:06:59 -07002018 << ec2;
Chris Cain3a2d04242021-05-28 16:57:10 -05002019 messages::internalError(aResp->res);
2020 return;
2021 }
Chris Cain3a2d04242021-05-28 16:57:10 -05002022
Ed Tanous002d39b2022-05-31 08:59:27 -07002023 aResp->res.jsonValue["PowerMode@Redfish.AllowableValues"] = {
2024 "Static", "MaximumPerformance", "PowerSaving"};
Chris Cain3a2d04242021-05-28 16:57:10 -05002025
Ed Tanous002d39b2022-05-31 08:59:27 -07002026 BMCWEB_LOG_DEBUG << "Current power mode: " << pmode;
2027 translatePowerMode(aResp, pmode);
2028 });
Chris Cain3a2d04242021-05-28 16:57:10 -05002029 },
2030 "xyz.openbmc_project.ObjectMapper",
2031 "/xyz/openbmc_project/object_mapper",
2032 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2033 std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
2034}
2035
2036/**
2037 * @brief Validate the specified mode is valid and return the PowerMode
2038 * name associated with that string
2039 *
2040 * @param[in] aResp Shared pointer for generating response message.
2041 * @param[in] modeString String representing the desired PowerMode
2042 *
2043 * @return PowerMode value or empty string if mode is not valid
2044 */
2045inline std::string
2046 validatePowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2047 const std::string& modeString)
2048{
2049 std::string mode;
2050
2051 if (modeString == "Static")
2052 {
2053 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.Static";
2054 }
2055 else if (modeString == "MaximumPerformance")
2056 {
George Liu0fda0f12021-11-16 10:06:17 +08002057 mode =
2058 "xyz.openbmc_project.Control.Power.Mode.PowerMode.MaximumPerformance";
Chris Cain3a2d04242021-05-28 16:57:10 -05002059 }
2060 else if (modeString == "PowerSaving")
2061 {
2062 mode = "xyz.openbmc_project.Control.Power.Mode.PowerMode.PowerSaving";
2063 }
2064 else
2065 {
2066 messages::propertyValueNotInList(aResp->res, modeString, "PowerMode");
2067 }
2068 return mode;
2069}
2070
2071/**
2072 * @brief Sets system power mode.
2073 *
2074 * @param[in] aResp Shared pointer for generating response message.
2075 * @param[in] pmode System power mode from request.
2076 *
2077 * @return None.
2078 */
2079inline void setPowerMode(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2080 const std::string& pmode)
2081{
2082 BMCWEB_LOG_DEBUG << "Set power mode.";
2083
2084 std::string powerMode = validatePowerMode(aResp, pmode);
2085 if (powerMode.empty())
2086 {
2087 return;
2088 }
2089
2090 // Get Power Mode object path:
2091 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08002092 [aResp,
2093 powerMode](const boost::system::error_code ec,
2094 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002095 if (ec)
2096 {
2097 BMCWEB_LOG_DEBUG << "DBUS response error on Power.Mode GetSubTree "
2098 << ec;
2099 // This is an optional D-Bus object, but user attempted to patch
2100 messages::internalError(aResp->res);
2101 return;
2102 }
2103 if (subtree.empty())
2104 {
2105 // This is an optional D-Bus object, but user attempted to patch
2106 messages::resourceNotFound(aResp->res, "ComputerSystem",
2107 "PowerMode");
2108 return;
2109 }
2110 if (subtree.size() > 1)
2111 {
2112 // More then one PowerMode object is not supported and is an
2113 // error
2114 BMCWEB_LOG_DEBUG
2115 << "Found more than 1 system D-Bus Power.Mode objects: "
2116 << subtree.size();
2117 messages::internalError(aResp->res);
2118 return;
2119 }
2120 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2121 {
2122 BMCWEB_LOG_DEBUG << "Power.Mode mapper error!";
2123 messages::internalError(aResp->res);
2124 return;
2125 }
2126 const std::string& path = subtree[0].first;
2127 const std::string& service = subtree[0].second.begin()->first;
2128 if (service.empty())
2129 {
2130 BMCWEB_LOG_DEBUG << "Power.Mode service mapper error!";
2131 messages::internalError(aResp->res);
2132 return;
2133 }
2134
2135 BMCWEB_LOG_DEBUG << "Setting power mode(" << powerMode << ") -> "
2136 << path;
2137
2138 // Set the Power Mode property
2139 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002140 [aResp](const boost::system::error_code ec2) {
2141 if (ec2)
Chris Cain3a2d04242021-05-28 16:57:10 -05002142 {
Chris Cain3a2d04242021-05-28 16:57:10 -05002143 messages::internalError(aResp->res);
2144 return;
2145 }
Ed Tanous002d39b2022-05-31 08:59:27 -07002146 },
2147 service, path, "org.freedesktop.DBus.Properties", "Set",
2148 "xyz.openbmc_project.Control.Power.Mode", "PowerMode",
2149 dbus::utility::DbusVariantType(powerMode));
Chris Cain3a2d04242021-05-28 16:57:10 -05002150 },
2151 "xyz.openbmc_project.ObjectMapper",
2152 "/xyz/openbmc_project/object_mapper",
2153 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2154 std::array<const char*, 1>{"xyz.openbmc_project.Control.Power.Mode"});
2155}
2156
2157/**
Yong Li51709ff2019-09-30 14:13:04 +08002158 * @brief Translates watchdog timeout action DBUS property value to redfish.
2159 *
2160 * @param[in] dbusAction The watchdog timeout action in D-BUS.
2161 *
2162 * @return Returns as a string, the timeout action in Redfish terms. If
2163 * translation cannot be done, returns an empty string.
2164 */
Ed Tanous23a21a12020-07-25 04:45:05 +00002165inline std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08002166{
2167 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
2168 {
2169 return "None";
2170 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002171 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.HardReset")
Yong Li51709ff2019-09-30 14:13:04 +08002172 {
2173 return "ResetSystem";
2174 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002175 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
Yong Li51709ff2019-09-30 14:13:04 +08002176 {
2177 return "PowerDown";
2178 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002179 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
Yong Li51709ff2019-09-30 14:13:04 +08002180 {
2181 return "PowerCycle";
2182 }
2183
2184 return "";
2185}
2186
2187/**
Yong Lic45f0082019-10-10 14:19:01 +08002188 *@brief Translates timeout action from Redfish to DBUS property value.
2189 *
2190 *@param[in] rfAction The timeout action in Redfish.
2191 *
2192 *@return Returns as a string, the time_out action as expected by DBUS.
2193 *If translation cannot be done, returns an empty string.
2194 */
2195
Ed Tanous23a21a12020-07-25 04:45:05 +00002196inline std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08002197{
2198 if (rfAction == "None")
2199 {
2200 return "xyz.openbmc_project.State.Watchdog.Action.None";
2201 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002202 if (rfAction == "PowerCycle")
Yong Lic45f0082019-10-10 14:19:01 +08002203 {
2204 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
2205 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002206 if (rfAction == "PowerDown")
Yong Lic45f0082019-10-10 14:19:01 +08002207 {
2208 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
2209 }
Ed Tanous3174e4d2020-10-07 11:41:22 -07002210 if (rfAction == "ResetSystem")
Yong Lic45f0082019-10-10 14:19:01 +08002211 {
2212 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
2213 }
2214
2215 return "";
2216}
2217
2218/**
Yong Li51709ff2019-09-30 14:13:04 +08002219 * @brief Retrieves host watchdog timer properties over DBUS
2220 *
2221 * @param[in] aResp Shared pointer for completing asynchronous calls.
2222 *
2223 * @return None.
2224 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002225inline void
2226 getHostWatchdogTimer(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
Yong Li51709ff2019-09-30 14:13:04 +08002227{
2228 BMCWEB_LOG_DEBUG << "Get host watchodg";
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002229 sdbusplus::asio::getAllProperties(
2230 *crow::connections::systemBus, "xyz.openbmc_project.Watchdog",
2231 "/xyz/openbmc_project/watchdog/host0",
2232 "xyz.openbmc_project.State.Watchdog",
Yong Li51709ff2019-09-30 14:13:04 +08002233 [aResp](const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002234 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002235 if (ec)
2236 {
2237 // watchdog service is stopped
2238 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2239 return;
2240 }
2241
2242 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
2243
2244 nlohmann::json& hostWatchdogTimer =
2245 aResp->res.jsonValue["HostWatchdogTimer"];
2246
2247 // watchdog service is running/enabled
2248 hostWatchdogTimer["Status"]["State"] = "Enabled";
2249
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002250 const bool* enabled = nullptr;
2251 const std::string* expireAction = nullptr;
2252
2253 const bool success = sdbusplus::unpackPropertiesNoThrow(
2254 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2255 "ExpireAction", expireAction);
2256
2257 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -07002258 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002259 messages::internalError(aResp->res);
2260 return;
Ed Tanous002d39b2022-05-31 08:59:27 -07002261 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002262
2263 if (enabled != nullptr)
2264 {
2265 hostWatchdogTimer["FunctionEnabled"] = *enabled;
2266 }
2267
2268 if (expireAction != nullptr)
2269 {
2270 std::string action = dbusToRfWatchdogAction(*expireAction);
2271 if (action.empty())
2272 {
2273 messages::internalError(aResp->res);
2274 return;
2275 }
2276 hostWatchdogTimer["TimeoutAction"] = action;
2277 }
2278 });
Yong Li51709ff2019-09-30 14:13:04 +08002279}
2280
2281/**
Yong Lic45f0082019-10-10 14:19:01 +08002282 * @brief Sets Host WatchDog Timer properties.
2283 *
2284 * @param[in] aResp Shared pointer for generating response message.
2285 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
2286 * RF request.
2287 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
2288 *
2289 * @return None.
2290 */
zhanghch058d1b46d2021-04-01 11:18:24 +08002291inline void setWDTProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
Yong Lic45f0082019-10-10 14:19:01 +08002292 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05002293 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08002294{
2295 BMCWEB_LOG_DEBUG << "Set host watchdog";
2296
2297 if (wdtTimeOutAction)
2298 {
2299 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
2300 // check if TimeOut Action is Valid
2301 if (wdtTimeOutActStr.empty())
2302 {
2303 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
2304 << *wdtTimeOutAction;
2305 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
2306 "TimeoutAction");
2307 return;
2308 }
2309
2310 crow::connections::systemBus->async_method_call(
2311 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002312 if (ec)
2313 {
2314 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2315 messages::internalError(aResp->res);
2316 return;
2317 }
Yong Lic45f0082019-10-10 14:19:01 +08002318 },
2319 "xyz.openbmc_project.Watchdog",
2320 "/xyz/openbmc_project/watchdog/host0",
2321 "org.freedesktop.DBus.Properties", "Set",
2322 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
Ed Tanous168e20c2021-12-13 14:39:53 -08002323 dbus::utility::DbusVariantType(wdtTimeOutActStr));
Yong Lic45f0082019-10-10 14:19:01 +08002324 }
2325
2326 if (wdtEnable)
2327 {
2328 crow::connections::systemBus->async_method_call(
2329 [aResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002330 if (ec)
2331 {
2332 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
2333 messages::internalError(aResp->res);
2334 return;
2335 }
Yong Lic45f0082019-10-10 14:19:01 +08002336 },
2337 "xyz.openbmc_project.Watchdog",
2338 "/xyz/openbmc_project/watchdog/host0",
2339 "org.freedesktop.DBus.Properties", "Set",
2340 "xyz.openbmc_project.State.Watchdog", "Enabled",
Ed Tanous168e20c2021-12-13 14:39:53 -08002341 dbus::utility::DbusVariantType(*wdtEnable));
Yong Lic45f0082019-10-10 14:19:01 +08002342 }
2343}
2344
Chris Cain37bbf982021-09-20 10:53:09 -05002345/**
2346 * @brief Parse the Idle Power Saver properties into json
2347 *
2348 * @param[in] aResp Shared pointer for completing asynchronous calls.
2349 * @param[in] properties IPS property data from DBus.
2350 *
2351 * @return true if successful
2352 */
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002353inline bool
2354 parseIpsProperties(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2355 const dbus::utility::DBusPropertiesMap& properties)
Chris Cain37bbf982021-09-20 10:53:09 -05002356{
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002357 const bool* enabled = nullptr;
2358 const uint8_t* enterUtilizationPercent = nullptr;
2359 const uint64_t* enterDwellTime = nullptr;
2360 const uint8_t* exitUtilizationPercent = nullptr;
2361 const uint64_t* exitDwellTime = nullptr;
2362
2363 const bool success = sdbusplus::unpackPropertiesNoThrow(
2364 dbus_utils::UnpackErrorPrinter(), properties, "Enabled", enabled,
2365 "EnterUtilizationPercent", enterUtilizationPercent,
2366 "ExitUtilizationPercent", exitUtilizationPercent, "ExitDwellTime",
2367 exitDwellTime);
2368
2369 if (!success)
Chris Cain37bbf982021-09-20 10:53:09 -05002370 {
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002371 return false;
2372 }
2373
2374 if (enabled != nullptr)
2375 {
2376 aResp->res.jsonValue["IdlePowerSaver"]["Enabled"] = *enabled;
2377 }
2378
2379 if (enterUtilizationPercent != nullptr)
2380 {
2381 aResp->res.jsonValue["IdlePowerSaver"]["EnterUtilizationPercent"] =
2382 *enterUtilizationPercent;
2383 }
2384
2385 if (enterDwellTime != nullptr)
2386 {
2387 const std::chrono::duration<uint64_t, std::milli> ms(*enterDwellTime);
2388 aResp->res.jsonValue["IdlePowerSaver"]["EnterDwellTimeSeconds"] =
2389 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2390 .count();
2391 }
2392
2393 if (exitUtilizationPercent != nullptr)
2394 {
2395 aResp->res.jsonValue["IdlePowerSaver"]["ExitUtilizationPercent"] =
2396 *exitUtilizationPercent;
2397 }
2398
2399 if (exitDwellTime != nullptr)
2400 {
2401 const std::chrono::duration<uint64_t, std::milli> ms(*exitDwellTime);
2402 aResp->res.jsonValue["IdlePowerSaver"]["ExitDwellTimeSeconds"] =
2403 std::chrono::duration_cast<std::chrono::duration<uint64_t>>(ms)
2404 .count();
Chris Cain37bbf982021-09-20 10:53:09 -05002405 }
2406
2407 return true;
2408}
2409
2410/**
2411 * @brief Retrieves host watchdog timer properties over DBUS
2412 *
2413 * @param[in] aResp Shared pointer for completing asynchronous calls.
2414 *
2415 * @return None.
2416 */
2417inline void getIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp)
2418{
2419 BMCWEB_LOG_DEBUG << "Get idle power saver parameters";
2420
2421 // Get IdlePowerSaver object path:
2422 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -08002423 [aResp](const boost::system::error_code ec,
2424 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002425 if (ec)
2426 {
2427 BMCWEB_LOG_DEBUG
2428 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2429 << ec;
2430 messages::internalError(aResp->res);
2431 return;
2432 }
2433 if (subtree.empty())
2434 {
2435 // This is an optional interface so just return
2436 // if there is no instance found
2437 BMCWEB_LOG_DEBUG << "No instances found";
2438 return;
2439 }
2440 if (subtree.size() > 1)
2441 {
2442 // More then one PowerIdlePowerSaver object is not supported and
2443 // is an error
2444 BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus "
2445 "Power.IdlePowerSaver objects: "
2446 << subtree.size();
2447 messages::internalError(aResp->res);
2448 return;
2449 }
2450 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2451 {
2452 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2453 messages::internalError(aResp->res);
2454 return;
2455 }
2456 const std::string& path = subtree[0].first;
2457 const std::string& service = subtree[0].second.begin()->first;
2458 if (service.empty())
2459 {
2460 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2461 messages::internalError(aResp->res);
2462 return;
2463 }
2464
2465 // Valid IdlePowerSaver object found, now read the current values
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002466 sdbusplus::asio::getAllProperties(
2467 *crow::connections::systemBus, service, path,
2468 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
Ed Tanous8a592812022-06-04 09:06:59 -07002469 [aResp](const boost::system::error_code ec2,
Jiaqing Zhao1e5b7c82022-08-15 16:15:52 +08002470 const dbus::utility::DBusPropertiesMap& properties) {
Ed Tanous8a592812022-06-04 09:06:59 -07002471 if (ec2)
Chris Cain37bbf982021-09-20 10:53:09 -05002472 {
Ed Tanous002d39b2022-05-31 08:59:27 -07002473 BMCWEB_LOG_ERROR
Ed Tanous8a592812022-06-04 09:06:59 -07002474 << "DBUS response error on IdlePowerSaver GetAll: " << ec2;
Chris Cain37bbf982021-09-20 10:53:09 -05002475 messages::internalError(aResp->res);
2476 return;
2477 }
2478
Ed Tanous002d39b2022-05-31 08:59:27 -07002479 if (!parseIpsProperties(aResp, properties))
2480 {
2481 messages::internalError(aResp->res);
2482 return;
2483 }
Krzysztof Grobelnybc1d29d2022-08-09 14:17:34 +02002484 });
Chris Cain37bbf982021-09-20 10:53:09 -05002485 },
2486 "xyz.openbmc_project.ObjectMapper",
2487 "/xyz/openbmc_project/object_mapper",
2488 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2489 std::array<const char*, 1>{
2490 "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
2491
2492 BMCWEB_LOG_DEBUG << "EXIT: Get idle power saver parameters";
2493}
2494
2495/**
2496 * @brief Sets Idle Power Saver properties.
2497 *
2498 * @param[in] aResp Shared pointer for generating response message.
2499 * @param[in] ipsEnable The IPS Enable value (true/false) from incoming
2500 * RF request.
2501 * @param[in] ipsEnterUtil The utilization limit to enter idle state.
2502 * @param[in] ipsEnterTime The time the utilization must be below ipsEnterUtil
2503 * before entering idle state.
2504 * @param[in] ipsExitUtil The utilization limit when exiting idle state.
2505 * @param[in] ipsExitTime The time the utilization must be above ipsExutUtil
2506 * before exiting idle state
2507 *
2508 * @return None.
2509 */
2510inline void setIdlePowerSaver(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
2511 const std::optional<bool> ipsEnable,
2512 const std::optional<uint8_t> ipsEnterUtil,
2513 const std::optional<uint64_t> ipsEnterTime,
2514 const std::optional<uint8_t> ipsExitUtil,
2515 const std::optional<uint64_t> ipsExitTime)
2516{
2517 BMCWEB_LOG_DEBUG << "Set idle power saver properties";
2518
2519 // Get IdlePowerSaver object path:
2520 crow::connections::systemBus->async_method_call(
2521 [aResp, ipsEnable, ipsEnterUtil, ipsEnterTime, ipsExitUtil,
Ed Tanousb9d36b42022-02-26 21:42:46 -08002522 ipsExitTime](const boost::system::error_code ec,
2523 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002524 if (ec)
2525 {
2526 BMCWEB_LOG_DEBUG
2527 << "DBUS response error on Power.IdlePowerSaver GetSubTree "
2528 << ec;
2529 messages::internalError(aResp->res);
2530 return;
2531 }
2532 if (subtree.empty())
2533 {
2534 // This is an optional D-Bus object, but user attempted to patch
2535 messages::resourceNotFound(aResp->res, "ComputerSystem",
2536 "IdlePowerSaver");
2537 return;
2538 }
2539 if (subtree.size() > 1)
2540 {
2541 // More then one PowerIdlePowerSaver object is not supported and
2542 // is an error
2543 BMCWEB_LOG_DEBUG
2544 << "Found more than 1 system D-Bus Power.IdlePowerSaver objects: "
2545 << subtree.size();
2546 messages::internalError(aResp->res);
2547 return;
2548 }
2549 if ((subtree[0].first.empty()) || (subtree[0].second.size() != 1))
2550 {
2551 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver mapper error!";
2552 messages::internalError(aResp->res);
2553 return;
2554 }
2555 const std::string& path = subtree[0].first;
2556 const std::string& service = subtree[0].second.begin()->first;
2557 if (service.empty())
2558 {
2559 BMCWEB_LOG_DEBUG << "Power.IdlePowerSaver service mapper error!";
2560 messages::internalError(aResp->res);
2561 return;
2562 }
Chris Cain37bbf982021-09-20 10:53:09 -05002563
Ed Tanous002d39b2022-05-31 08:59:27 -07002564 // Valid Power IdlePowerSaver object found, now set any values that
2565 // need to be updated
Chris Cain37bbf982021-09-20 10:53:09 -05002566
Ed Tanous002d39b2022-05-31 08:59:27 -07002567 if (ipsEnable)
2568 {
2569 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002570 [aResp](const boost::system::error_code ec2) {
2571 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002572 {
Ed Tanous8a592812022-06-04 09:06:59 -07002573 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002574 messages::internalError(aResp->res);
2575 return;
2576 }
2577 },
2578 service, path, "org.freedesktop.DBus.Properties", "Set",
2579 "xyz.openbmc_project.Control.Power.IdlePowerSaver", "Enabled",
2580 dbus::utility::DbusVariantType(*ipsEnable));
2581 }
2582 if (ipsEnterUtil)
2583 {
2584 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002585 [aResp](const boost::system::error_code ec2) {
2586 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002587 {
Ed Tanous8a592812022-06-04 09:06:59 -07002588 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002589 messages::internalError(aResp->res);
2590 return;
2591 }
2592 },
2593 service, path, "org.freedesktop.DBus.Properties", "Set",
2594 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2595 "EnterUtilizationPercent",
2596 dbus::utility::DbusVariantType(*ipsEnterUtil));
2597 }
2598 if (ipsEnterTime)
2599 {
2600 // Convert from seconds into milliseconds for DBus
2601 const uint64_t timeMilliseconds = *ipsEnterTime * 1000;
2602 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002603 [aResp](const boost::system::error_code ec2) {
2604 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002605 {
Ed Tanous8a592812022-06-04 09:06:59 -07002606 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002607 messages::internalError(aResp->res);
2608 return;
2609 }
2610 },
2611 service, path, "org.freedesktop.DBus.Properties", "Set",
2612 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2613 "EnterDwellTime",
2614 dbus::utility::DbusVariantType(timeMilliseconds));
2615 }
2616 if (ipsExitUtil)
2617 {
2618 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002619 [aResp](const boost::system::error_code ec2) {
2620 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002621 {
Ed Tanous8a592812022-06-04 09:06:59 -07002622 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002623 messages::internalError(aResp->res);
2624 return;
2625 }
2626 },
2627 service, path, "org.freedesktop.DBus.Properties", "Set",
2628 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2629 "ExitUtilizationPercent",
2630 dbus::utility::DbusVariantType(*ipsExitUtil));
2631 }
2632 if (ipsExitTime)
2633 {
2634 // Convert from seconds into milliseconds for DBus
2635 const uint64_t timeMilliseconds = *ipsExitTime * 1000;
2636 crow::connections::systemBus->async_method_call(
Ed Tanous8a592812022-06-04 09:06:59 -07002637 [aResp](const boost::system::error_code ec2) {
2638 if (ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002639 {
Ed Tanous8a592812022-06-04 09:06:59 -07002640 BMCWEB_LOG_DEBUG << "DBUS response error " << ec2;
Ed Tanous002d39b2022-05-31 08:59:27 -07002641 messages::internalError(aResp->res);
2642 return;
2643 }
2644 },
2645 service, path, "org.freedesktop.DBus.Properties", "Set",
2646 "xyz.openbmc_project.Control.Power.IdlePowerSaver",
2647 "ExitDwellTime",
2648 dbus::utility::DbusVariantType(timeMilliseconds));
2649 }
Chris Cain37bbf982021-09-20 10:53:09 -05002650 },
2651 "xyz.openbmc_project.ObjectMapper",
2652 "/xyz/openbmc_project/object_mapper",
2653 "xyz.openbmc_project.ObjectMapper", "GetSubTree", "/", int32_t(0),
2654 std::array<const char*, 1>{
2655 "xyz.openbmc_project.Control.Power.IdlePowerSaver"});
2656
2657 BMCWEB_LOG_DEBUG << "EXIT: Set idle power saver parameters";
2658}
2659
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002660inline void handleComputerSystemHead(
2661 crow::App& app, const crow::Request& req,
2662 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2663{
2664 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2665 {
2666 return;
2667 }
2668 asyncResp->res.addHeader(
2669 boost::beast::http::field::link,
2670 "</redfish/v1/JsonSchemas/ComputerSystemCollection/ComputerSystemCollection.json>; rel=describedby");
2671}
2672
Yong Lic45f0082019-10-10 14:19:01 +08002673/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002674 * SystemsCollection derived class for delivering ComputerSystems Collection
2675 * Schema
2676 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002677inline void requestRoutesSystemsCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002678{
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002679 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002680 .privileges(redfish::privileges::headComputerSystemCollection)
2681 .methods(boost::beast::http::verb::head)(
2682 std::bind_front(handleComputerSystemHead, std::ref(app)));
2683
2684 BMCWEB_ROUTE(app, "/redfish/v1/Systems/")
Ed Tanoused398212021-06-09 17:05:54 -07002685 .privileges(redfish::privileges::getComputerSystemCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002686 .methods(boost::beast::http::verb::get)(
Ed Tanousf4c99e72021-10-04 17:02:43 -07002687 [&app](const crow::Request& req,
2688 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002689 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002690 {
2691 return;
2692 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002693
2694 asyncResp->res.addHeader(
2695 boost::beast::http::field::link,
2696 "</redfish/v1/JsonSchemas/ComputerSystemCollection.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002697 asyncResp->res.jsonValue["@odata.type"] =
2698 "#ComputerSystemCollection.ComputerSystemCollection";
2699 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
2700 asyncResp->res.jsonValue["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002701
Ed Tanous002d39b2022-05-31 08:59:27 -07002702 sdbusplus::asio::getProperty<std::string>(
2703 *crow::connections::systemBus, "xyz.openbmc_project.Settings",
2704 "/xyz/openbmc_project/network/hypervisor",
2705 "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
Ed Tanous8a592812022-06-04 09:06:59 -07002706 [asyncResp](const boost::system::error_code ec2,
Ed Tanous002d39b2022-05-31 08:59:27 -07002707 const std::string& /*hostName*/) {
2708 nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"];
2709 ifaceArray = nlohmann::json::array();
2710 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Ed Tanous14766872022-03-15 10:44:42 -07002711
Ed Tanous002d39b2022-05-31 08:59:27 -07002712 nlohmann::json::object_t system;
2713 system["@odata.id"] = "/redfish/v1/Systems/system";
2714 ifaceArray.push_back(std::move(system));
2715 count = ifaceArray.size();
Ed Tanous8a592812022-06-04 09:06:59 -07002716 if (!ec2)
Ed Tanous002d39b2022-05-31 08:59:27 -07002717 {
2718 BMCWEB_LOG_DEBUG << "Hypervisor is available";
2719 nlohmann::json::object_t hypervisor;
2720 hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
2721 ifaceArray.push_back(std::move(hypervisor));
2722 count = ifaceArray.size();
2723 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002724 });
Ed Tanous002d39b2022-05-31 08:59:27 -07002725 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002726}
Sunitha Harish462023a2020-02-19 08:34:59 -06002727
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002728/**
2729 * Function transceives data with dbus directly.
2730 */
Ed Tanous4f48d5f2021-06-21 08:27:45 -07002731inline void doNMI(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002732{
2733 constexpr char const* serviceName = "xyz.openbmc_project.Control.Host.NMI";
2734 constexpr char const* objectPath = "/xyz/openbmc_project/control/host0/nmi";
2735 constexpr char const* interfaceName =
2736 "xyz.openbmc_project.Control.Host.NMI";
2737 constexpr char const* method = "NMI";
2738
2739 crow::connections::systemBus->async_method_call(
2740 [asyncResp](const boost::system::error_code ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -07002741 if (ec)
2742 {
2743 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
2744 messages::internalError(asyncResp->res);
2745 return;
2746 }
2747 messages::success(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002748 },
2749 serviceName, objectPath, interfaceName, method);
2750}
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002751
2752/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07002753 * SystemActionsReset class supports handle POST method for Reset action.
2754 * The class retrieves and sends data directly to D-Bus.
2755 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002756inline void requestRoutesSystemActionsReset(App& app)
Ed Tanouscc340dd2018-08-29 13:43:38 -07002757{
Ed Tanouscc340dd2018-08-29 13:43:38 -07002758 /**
2759 * Function handles POST method request.
2760 * Analyzes POST body message before sends Reset request data to D-Bus.
2761 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002762 BMCWEB_ROUTE(app,
2763 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -07002764 .privileges(redfish::privileges::postComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002765 .methods(boost::beast::http::verb::post)(
2766 [&app](const crow::Request& req,
2767 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002768 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002769 {
2770 return;
2771 }
2772 std::string resetType;
2773 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType",
2774 resetType))
2775 {
2776 return;
2777 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07002778
Ed Tanous002d39b2022-05-31 08:59:27 -07002779 // Get the command and host vs. chassis
2780 std::string command;
2781 bool hostCommand = true;
2782 if ((resetType == "On") || (resetType == "ForceOn"))
2783 {
2784 command = "xyz.openbmc_project.State.Host.Transition.On";
2785 hostCommand = true;
2786 }
2787 else if (resetType == "ForceOff")
2788 {
2789 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
2790 hostCommand = false;
2791 }
2792 else if (resetType == "ForceRestart")
2793 {
2794 command =
2795 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
2796 hostCommand = true;
2797 }
2798 else if (resetType == "GracefulShutdown")
2799 {
2800 command = "xyz.openbmc_project.State.Host.Transition.Off";
2801 hostCommand = true;
2802 }
2803 else if (resetType == "GracefulRestart")
2804 {
2805 command =
2806 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
2807 hostCommand = true;
2808 }
2809 else if (resetType == "PowerCycle")
2810 {
2811 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
2812 hostCommand = true;
2813 }
2814 else if (resetType == "Nmi")
2815 {
2816 doNMI(asyncResp);
2817 return;
2818 }
2819 else
2820 {
2821 messages::actionParameterUnknown(asyncResp->res, "Reset",
2822 resetType);
2823 return;
2824 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07002825
Ed Tanous002d39b2022-05-31 08:59:27 -07002826 if (hostCommand)
2827 {
2828 crow::connections::systemBus->async_method_call(
2829 [asyncResp, resetType](const boost::system::error_code ec) {
2830 if (ec)
2831 {
2832 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2833 if (ec.value() == boost::asio::error::invalid_argument)
2834 {
2835 messages::actionParameterNotSupported(
2836 asyncResp->res, resetType, "Reset");
2837 }
2838 else
2839 {
2840 messages::internalError(asyncResp->res);
2841 }
2842 return;
2843 }
2844 messages::success(asyncResp->res);
2845 },
2846 "xyz.openbmc_project.State.Host",
2847 "/xyz/openbmc_project/state/host0",
2848 "org.freedesktop.DBus.Properties", "Set",
2849 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
2850 dbus::utility::DbusVariantType{command});
2851 }
2852 else
2853 {
2854 crow::connections::systemBus->async_method_call(
2855 [asyncResp, resetType](const boost::system::error_code ec) {
2856 if (ec)
2857 {
2858 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
2859 if (ec.value() == boost::asio::error::invalid_argument)
2860 {
2861 messages::actionParameterNotSupported(
2862 asyncResp->res, resetType, "Reset");
2863 }
2864 else
2865 {
2866 messages::internalError(asyncResp->res);
2867 }
2868 return;
2869 }
2870 messages::success(asyncResp->res);
2871 },
2872 "xyz.openbmc_project.State.Chassis",
2873 "/xyz/openbmc_project/state/chassis0",
2874 "org.freedesktop.DBus.Properties", "Set",
2875 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
2876 dbus::utility::DbusVariantType{command});
2877 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002878 });
2879}
Ed Tanouscc340dd2018-08-29 13:43:38 -07002880
Ed Tanous38c8a6f2022-09-01 16:37:27 -07002881inline void handleComputerSystemCollectionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002882 App& app, const crow::Request& req,
2883 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2884{
2885 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2886 {
2887 return;
2888 }
2889
2890 asyncResp->res.addHeader(
2891 boost::beast::http::field::link,
2892 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
2893}
2894
Ed Tanouscc340dd2018-08-29 13:43:38 -07002895/**
Ed Tanous66173382018-08-15 18:20:59 -07002896 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002897 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07002898inline void requestRoutesSystems(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -07002899{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002900
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002901 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/")
2902 .privileges(redfish::privileges::headComputerSystem)
2903 .methods(boost::beast::http::verb::head)(
2904 std::bind_front(handleComputerSystemCollectionHead, std::ref(app)));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002905 /**
2906 * Functions triggers appropriate requests on DBus
2907 */
Ed Tanous22d268c2022-05-19 09:39:07 -07002908 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07002909 .privileges(redfish::privileges::getComputerSystem)
Ed Tanous002d39b2022-05-31 08:59:27 -07002910 .methods(boost::beast::http::verb::get)(
2911 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07002912 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2913 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00002914 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07002915 {
2916 return;
2917 }
Ed Tanous22d268c2022-05-19 09:39:07 -07002918 if (systemName != "system")
2919 {
2920 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
2921 systemName);
2922 return;
2923 }
Ed Tanousdd60b9e2022-07-07 17:03:54 -07002924 asyncResp->res.addHeader(
2925 boost::beast::http::field::link,
2926 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
Ed Tanous002d39b2022-05-31 08:59:27 -07002927 asyncResp->res.jsonValue["@odata.type"] =
2928 "#ComputerSystem.v1_16_0.ComputerSystem";
2929 asyncResp->res.jsonValue["Name"] = "system";
2930 asyncResp->res.jsonValue["Id"] = "system";
2931 asyncResp->res.jsonValue["SystemType"] = "Physical";
2932 asyncResp->res.jsonValue["Description"] = "Computer System";
2933 asyncResp->res.jsonValue["ProcessorSummary"]["Count"] = 0;
2934 asyncResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
2935 "Disabled";
2936 asyncResp->res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] =
2937 uint64_t(0);
2938 asyncResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
2939 "Disabled";
2940 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07002941
Ed Tanous002d39b2022-05-31 08:59:27 -07002942 asyncResp->res.jsonValue["Processors"]["@odata.id"] =
2943 "/redfish/v1/Systems/system/Processors";
2944 asyncResp->res.jsonValue["Memory"]["@odata.id"] =
2945 "/redfish/v1/Systems/system/Memory";
2946 asyncResp->res.jsonValue["Storage"]["@odata.id"] =
2947 "/redfish/v1/Systems/system/Storage";
Ed Tanous029573d2019-02-01 10:57:49 -08002948
Ed Tanous002d39b2022-05-31 08:59:27 -07002949 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] =
2950 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset";
2951 asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]
2952 ["@Redfish.ActionInfo"] =
2953 "/redfish/v1/Systems/system/ResetActionInfo";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002954
Ed Tanous002d39b2022-05-31 08:59:27 -07002955 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
2956 "/redfish/v1/Systems/system/LogServices";
2957 asyncResp->res.jsonValue["Bios"]["@odata.id"] =
2958 "/redfish/v1/Systems/system/Bios";
Jason M. Billsc4bf6372018-11-05 13:48:27 -08002959
Ed Tanous002d39b2022-05-31 08:59:27 -07002960 nlohmann::json::array_t managedBy;
2961 nlohmann::json& manager = managedBy.emplace_back();
2962 manager["@odata.id"] = "/redfish/v1/Managers/bmc";
2963 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
2964 asyncResp->res.jsonValue["Status"]["Health"] = "OK";
2965 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002966
Ed Tanous002d39b2022-05-31 08:59:27 -07002967 // Fill in SerialConsole info
2968 asyncResp->res.jsonValue["SerialConsole"]["MaxConcurrentSessions"] = 15;
2969 asyncResp->res.jsonValue["SerialConsole"]["IPMI"]["ServiceEnabled"] =
2970 true;
Ed Tanous14766872022-03-15 10:44:42 -07002971
Ed Tanous002d39b2022-05-31 08:59:27 -07002972 // TODO (Gunnar): Should look for obmc-console-ssh@2200.service
2973 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["ServiceEnabled"] =
2974 true;
2975 asyncResp->res.jsonValue["SerialConsole"]["SSH"]["Port"] = 2200;
2976 asyncResp->res
2977 .jsonValue["SerialConsole"]["SSH"]["HotKeySequenceDisplay"] =
2978 "Press ~. to exit console";
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002979
2980#ifdef BMCWEB_ENABLE_KVM
Ed Tanous002d39b2022-05-31 08:59:27 -07002981 // Fill in GraphicalConsole info
2982 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
2983 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
2984 4;
Ed Tanous613dabe2022-07-09 11:17:36 -07002985 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
2986 nlohmann::json::array_t({"KVMIP"});
Ed Tanous14766872022-03-15 10:44:42 -07002987
Gunnar Mills0e8ac5e2020-11-06 15:33:24 -06002988#endif // BMCWEB_ENABLE_KVM
George Liu7a1dbc42022-12-07 16:03:22 +08002989 constexpr std::array<std::string_view, 4> inventoryForSystems{
Ed Tanous002d39b2022-05-31 08:59:27 -07002990 "xyz.openbmc_project.Inventory.Item.Dimm",
2991 "xyz.openbmc_project.Inventory.Item.Cpu",
2992 "xyz.openbmc_project.Inventory.Item.Drive",
2993 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07002994
Ed Tanous002d39b2022-05-31 08:59:27 -07002995 auto health = std::make_shared<HealthPopulate>(asyncResp);
George Liu7a1dbc42022-12-07 16:03:22 +08002996 dbus::utility::getSubTreePaths(
2997 "/", 0, inventoryForSystems,
2998 [health](const boost::system::error_code& ec,
Ed Tanous002d39b2022-05-31 08:59:27 -07002999 const std::vector<std::string>& resp) {
3000 if (ec)
3001 {
3002 // no inventory
3003 return;
3004 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003005
Ed Tanous002d39b2022-05-31 08:59:27 -07003006 health->inventory = resp;
George Liu7a1dbc42022-12-07 16:03:22 +08003007 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003008
Ed Tanous002d39b2022-05-31 08:59:27 -07003009 health->populate();
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003010
Ed Tanous002d39b2022-05-31 08:59:27 -07003011 getMainChassisId(asyncResp,
3012 [](const std::string& chassisId,
3013 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
3014 nlohmann::json::array_t chassisArray;
3015 nlohmann::json& chassis = chassisArray.emplace_back();
3016 chassis["@odata.id"] = "/redfish/v1/Chassis/" + chassisId;
3017 aRsp->res.jsonValue["Links"]["Chassis"] = std::move(chassisArray);
3018 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003019
Ed Tanous002d39b2022-05-31 08:59:27 -07003020 getLocationIndicatorActive(asyncResp);
3021 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
3022 getIndicatorLedState(asyncResp);
3023 getComputerSystem(asyncResp, health);
3024 getHostState(asyncResp);
3025 getBootProperties(asyncResp);
3026 getBootProgress(asyncResp);
Hieu Huynhb6d5d452022-10-07 09:41:46 +00003027 getBootProgressLastStateTime(asyncResp);
Ed Tanous002d39b2022-05-31 08:59:27 -07003028 getPCIeDeviceList(asyncResp, "PCIeDevices");
3029 getHostWatchdogTimer(asyncResp);
3030 getPowerRestorePolicy(asyncResp);
3031 getAutomaticRetry(asyncResp);
3032 getLastResetTime(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003033#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
Ed Tanous002d39b2022-05-31 08:59:27 -07003034 getProvisioningStatus(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003035#endif
Ed Tanous002d39b2022-05-31 08:59:27 -07003036 getTrustedModuleRequiredToBoot(asyncResp);
3037 getPowerMode(asyncResp);
3038 getIdlePowerSaver(asyncResp);
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003039 });
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003040
Ed Tanous22d268c2022-05-19 09:39:07 -07003041 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -07003042 .privileges(redfish::privileges::patchComputerSystem)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003043 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003044 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003045 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3046 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003047 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003048 {
3049 return;
3050 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003051 if (systemName != "system")
3052 {
3053 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3054 systemName);
3055 return;
3056 }
3057
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003058 asyncResp->res.addHeader(
3059 boost::beast::http::field::link,
3060 "</redfish/v1/JsonSchemas/ComputerSystem/ComputerSystem.json>; rel=describedby");
3061
Ed Tanous002d39b2022-05-31 08:59:27 -07003062 std::optional<bool> locationIndicatorActive;
3063 std::optional<std::string> indicatorLed;
3064 std::optional<std::string> assetTag;
3065 std::optional<std::string> powerRestorePolicy;
3066 std::optional<std::string> powerMode;
3067 std::optional<bool> wdtEnable;
3068 std::optional<std::string> wdtTimeOutAction;
3069 std::optional<std::string> bootSource;
3070 std::optional<std::string> bootType;
3071 std::optional<std::string> bootEnable;
3072 std::optional<std::string> bootAutomaticRetry;
3073 std::optional<bool> bootTrustedModuleRequired;
3074 std::optional<bool> ipsEnable;
3075 std::optional<uint8_t> ipsEnterUtil;
3076 std::optional<uint64_t> ipsEnterTime;
3077 std::optional<uint8_t> ipsExitUtil;
3078 std::optional<uint64_t> ipsExitTime;
Jiaqing Zhao550a6bf2022-04-26 17:54:52 +08003079
Ed Tanous002d39b2022-05-31 08:59:27 -07003080 // clang-format off
Ed Tanous22d268c2022-05-19 09:39:07 -07003081 if (!json_util::readJsonPatch(
3082 req, asyncResp->res,
3083 "IndicatorLED", indicatorLed,
3084 "LocationIndicatorActive", locationIndicatorActive,
3085 "AssetTag", assetTag,
3086 "PowerRestorePolicy", powerRestorePolicy,
3087 "PowerMode", powerMode,
3088 "HostWatchdogTimer/FunctionEnabled", wdtEnable,
3089 "HostWatchdogTimer/TimeoutAction", wdtTimeOutAction,
3090 "Boot/BootSourceOverrideTarget", bootSource,
3091 "Boot/BootSourceOverrideMode", bootType,
3092 "Boot/BootSourceOverrideEnabled", bootEnable,
3093 "Boot/AutomaticRetryConfig", bootAutomaticRetry,
3094 "Boot/TrustedModuleRequiredToBoot", bootTrustedModuleRequired,
3095 "IdlePowerSaver/Enabled", ipsEnable,
3096 "IdlePowerSaver/EnterUtilizationPercent", ipsEnterUtil,
3097 "IdlePowerSaver/EnterDwellTimeSeconds", ipsEnterTime,
3098 "IdlePowerSaver/ExitUtilizationPercent", ipsExitUtil,
3099 "IdlePowerSaver/ExitDwellTimeSeconds", ipsExitTime))
3100 {
3101 return;
3102 }
Ed Tanous002d39b2022-05-31 08:59:27 -07003103 // clang-format on
James Feistb49ac872019-05-21 15:12:01 -07003104
Ed Tanous002d39b2022-05-31 08:59:27 -07003105 asyncResp->res.result(boost::beast::http::status::no_content);
James Feistb49ac872019-05-21 15:12:01 -07003106
Ed Tanous002d39b2022-05-31 08:59:27 -07003107 if (assetTag)
3108 {
3109 setAssetTag(asyncResp, *assetTag);
3110 }
James Feistb49ac872019-05-21 15:12:01 -07003111
Ed Tanous002d39b2022-05-31 08:59:27 -07003112 if (wdtEnable || wdtTimeOutAction)
3113 {
3114 setWDTProperties(asyncResp, wdtEnable, wdtTimeOutAction);
3115 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003116
Ed Tanous002d39b2022-05-31 08:59:27 -07003117 if (bootSource || bootType || bootEnable)
3118 {
3119 setBootProperties(asyncResp, bootSource, bootType, bootEnable);
3120 }
3121 if (bootAutomaticRetry)
3122 {
3123 setAutomaticRetry(asyncResp, *bootAutomaticRetry);
3124 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003125
Ed Tanous002d39b2022-05-31 08:59:27 -07003126 if (bootTrustedModuleRequired)
3127 {
3128 setTrustedModuleRequiredToBoot(asyncResp,
3129 *bootTrustedModuleRequired);
3130 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003131
Ed Tanous002d39b2022-05-31 08:59:27 -07003132 if (locationIndicatorActive)
3133 {
3134 setLocationIndicatorActive(asyncResp, *locationIndicatorActive);
3135 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003136
Ed Tanous002d39b2022-05-31 08:59:27 -07003137 // TODO (Gunnar): Remove IndicatorLED after enough time has
3138 // passed
3139 if (indicatorLed)
3140 {
3141 setIndicatorLedState(asyncResp, *indicatorLed);
3142 asyncResp->res.addHeader(boost::beast::http::field::warning,
3143 "299 - \"IndicatorLED is deprecated. Use "
3144 "LocationIndicatorActive instead.\"");
3145 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003146
Ed Tanous002d39b2022-05-31 08:59:27 -07003147 if (powerRestorePolicy)
3148 {
3149 setPowerRestorePolicy(asyncResp, *powerRestorePolicy);
3150 }
Chris Cain3a2d04242021-05-28 16:57:10 -05003151
Ed Tanous002d39b2022-05-31 08:59:27 -07003152 if (powerMode)
3153 {
3154 setPowerMode(asyncResp, *powerMode);
3155 }
Chris Cain37bbf982021-09-20 10:53:09 -05003156
Ed Tanous002d39b2022-05-31 08:59:27 -07003157 if (ipsEnable || ipsEnterUtil || ipsEnterTime || ipsExitUtil ||
3158 ipsExitTime)
3159 {
3160 setIdlePowerSaver(asyncResp, ipsEnable, ipsEnterUtil, ipsEnterTime,
3161 ipsExitUtil, ipsExitTime);
3162 }
3163 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003164}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303165
Ed Tanous38c8a6f2022-09-01 16:37:27 -07003166inline void handleSystemCollectionResetActionHead(
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003167 crow::App& app, const crow::Request& req,
3168 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3169{
3170 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3171 {
3172 return;
3173 }
3174 asyncResp->res.addHeader(
3175 boost::beast::http::field::link,
3176 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
3177}
3178
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303179/**
3180 * SystemResetActionInfo derived class for delivering Computer Systems
3181 * ResetType AllowableValues using ResetInfo schema.
3182 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003183inline void requestRoutesSystemResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303184{
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003185 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/ResetActionInfo/")
3186 .privileges(redfish::privileges::headActionInfo)
3187 .methods(boost::beast::http::verb::head)(std::bind_front(
3188 handleSystemCollectionResetActionHead, std::ref(app)));
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +05303189 /**
3190 * Functions triggers appropriate requests on DBus
3191 */
Ed Tanous22d268c2022-05-19 09:39:07 -07003192 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -07003193 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003194 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -07003195 [&app](const crow::Request& req,
Ed Tanous22d268c2022-05-19 09:39:07 -07003196 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
3197 const std::string& systemName) {
Carson Labrado3ba00072022-06-06 19:40:56 +00003198 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
Ed Tanous002d39b2022-05-31 08:59:27 -07003199 {
3200 return;
3201 }
Ed Tanous22d268c2022-05-19 09:39:07 -07003202 if (systemName != "system")
3203 {
3204 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
3205 systemName);
3206 return;
3207 }
3208
Ed Tanousdd60b9e2022-07-07 17:03:54 -07003209 asyncResp->res.addHeader(
3210 boost::beast::http::field::link,
3211 "</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
Ed Tanous14766872022-03-15 10:44:42 -07003212
Ed Tanous002d39b2022-05-31 08:59:27 -07003213 asyncResp->res.jsonValue["@odata.id"] =
3214 "/redfish/v1/Systems/system/ResetActionInfo";
3215 asyncResp->res.jsonValue["@odata.type"] =
3216 "#ActionInfo.v1_1_2.ActionInfo";
3217 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
3218 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
Nan Zhou3215e702022-06-01 16:55:13 +00003219
3220 nlohmann::json::array_t parameters;
3221 nlohmann::json::object_t parameter;
3222
3223 parameter["Name"] = "ResetType";
3224 parameter["Required"] = true;
3225 parameter["DataType"] = "String";
3226 nlohmann::json::array_t allowableValues;
3227 allowableValues.emplace_back("On");
3228 allowableValues.emplace_back("ForceOff");
3229 allowableValues.emplace_back("ForceOn");
3230 allowableValues.emplace_back("ForceRestart");
3231 allowableValues.emplace_back("GracefulRestart");
3232 allowableValues.emplace_back("GracefulShutdown");
3233 allowableValues.emplace_back("PowerCycle");
3234 allowableValues.emplace_back("Nmi");
3235 parameter["AllowableValues"] = std::move(allowableValues);
3236 parameters.emplace_back(std::move(parameter));
3237
3238 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
Ed Tanous002d39b2022-05-31 08:59:27 -07003239 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -07003240}
Ed Tanous1abe55e2018-09-05 08:30:59 -07003241} // namespace redfish