blob: 422b2f75dec53ff8ee92658cde50f84ae041aba1 [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
James Feistb49ac872019-05-21 15:12:01 -070018#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080019#include "led.hpp"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080020#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080021#include "redfish_util.hpp"
22
Ed Tanous9712f8a2018-09-21 13:38:49 -070023#include <boost/container/flat_map.hpp>
24#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060025#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020026#include <utils/json_utils.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050027
Ed Tanousabf2add2019-01-22 16:40:12 -080028#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020029
Ed Tanous1abe55e2018-09-05 08:30:59 -070030namespace redfish
31{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020032
Alpana Kumari9d3ae102019-04-12 06:49:32 -050033/**
34 * @brief Updates the Functional State of DIMMs
35 *
36 * @param[in] aResp Shared pointer for completing asynchronous calls
37 * @param[in] dimmState Dimm's Functional state, true/false
38 *
39 * @return None.
40 */
41void updateDimmProperties(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050042 const std::variant<bool>& dimmState)
Alpana Kumari9d3ae102019-04-12 06:49:32 -050043{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050044 const bool* isDimmFunctional = std::get_if<bool>(&dimmState);
Alpana Kumari9d3ae102019-04-12 06:49:32 -050045 if (isDimmFunctional == nullptr)
46 {
47 messages::internalError(aResp->res);
48 return;
49 }
Gunnar Mills698654b2019-10-16 13:17:37 -050050 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050051
Gunnar Mills4e0453b2020-07-08 14:00:30 -050052 // Set it as Enabled if at least one DIMM is functional
Alpana Kumari9d3ae102019-04-12 06:49:32 -050053 // Update STATE only if previous State was DISABLED and current Dimm is
54 // ENABLED.
Gunnar Mills1214b7e2020-06-04 10:11:30 -050055 nlohmann::json& prevMemSummary =
Alpana Kumari9d3ae102019-04-12 06:49:32 -050056 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
57 if (prevMemSummary == "Disabled")
58 {
59 if (*isDimmFunctional == true)
60 {
61 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
62 "Enabled";
63 }
64 }
65}
66
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050067/*
68 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
69 *
70 * @param[in] aResp Shared pointer for completing asynchronous calls
71 * @param[in] cpuPresenceState CPU present or not
72 *
73 * @return None.
74 */
75void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050076 const std::variant<bool>& cpuPresenceState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050077{
Gunnar Mills1214b7e2020-06-04 10:11:30 -050078 const bool* isCpuPresent = std::get_if<bool>(&cpuPresenceState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050079
80 if (isCpuPresent == nullptr)
81 {
82 messages::internalError(aResp->res);
83 return;
84 }
Gunnar Mills698654b2019-10-16 13:17:37 -050085 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050087 if (*isCpuPresent == true)
88 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 nlohmann::json& procCount =
James Feistb4b95952019-12-05 15:01:55 -080090 aResp->res.jsonValue["ProcessorSummary"]["Count"];
91 auto procCountPtr =
Gunnar Mills1214b7e2020-06-04 10:11:30 -050092 procCount.get_ptr<nlohmann::json::number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -080093 if (procCountPtr != nullptr)
94 {
95 // shouldn't be possible to be nullptr
96 *procCountPtr += 1;
97 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050098 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050099}
100
101/*
102 * @brief Update "ProcessorSummary" "Status" "State" based on
103 * CPU Functional State
104 *
105 * @param[in] aResp Shared pointer for completing asynchronous calls
106 * @param[in] cpuFunctionalState is CPU functional true/false
107 *
108 * @return None.
109 */
110void modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500111 const std::variant<bool>& cpuFunctionalState)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500112{
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500113 const bool* isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114
115 if (isCpuFunctional == nullptr)
116 {
117 messages::internalError(aResp->res);
118 return;
119 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500120 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500121
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500122 nlohmann::json& prevProcState =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500123 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
124
Gunnar Mills4e0453b2020-07-08 14:00:30 -0500125 // Set it as Enabled if at least one CPU is functional
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500126 // Update STATE only if previous State was Non_Functional and current CPU is
127 // Functional.
128 if (prevProcState == "Disabled")
129 {
130 if (*isCpuFunctional == true)
131 {
132 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
133 "Enabled";
134 }
135 }
136}
137
138/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700139 * @brief Retrieves computer system properties over dbus
140 *
141 * @param[in] aResp Shared pointer for completing asynchronous calls
142 * @param[in] name Computer system name from request
143 *
144 * @return None.
145 */
James Feist5bc2dc82019-10-22 14:33:16 -0700146void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
147 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700148{
Ed Tanous6c34de42018-08-29 13:37:36 -0700149 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500150
Ed Tanous6c34de42018-08-29 13:37:36 -0700151 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700152 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700153 const boost::system::error_code ec,
154 const std::vector<std::pair<
155 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500156 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
157 subtree) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700158 if (ec)
159 {
160 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700161 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700162 return;
163 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700164 // Iterate over all retrieved ObjectPaths.
165 for (const std::pair<std::string,
166 std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500167 std::string, std::vector<std::string>>>>&
168 object : subtree)
Ed Tanous6c34de42018-08-29 13:37:36 -0700169 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500170 const std::string& path = object.first;
Ed Tanous6c34de42018-08-29 13:37:36 -0700171 BMCWEB_LOG_DEBUG << "Got path: " << path;
172 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500173 std::pair<std::string, std::vector<std::string>>>&
174 connectionNames = object.second;
Ed Tanous6c34de42018-08-29 13:37:36 -0700175 if (connectionNames.size() < 1)
176 {
177 continue;
178 }
Ed Tanous029573d2019-02-01 10:57:49 -0800179
James Feist5bc2dc82019-10-22 14:33:16 -0700180 auto memoryHealth = std::make_shared<HealthPopulate>(
181 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
182
183 auto cpuHealth = std::make_shared<HealthPopulate>(
184 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
185
186 systemHealth->children.emplace_back(memoryHealth);
187 systemHealth->children.emplace_back(cpuHealth);
188
Ed Tanous029573d2019-02-01 10:57:49 -0800189 // This is not system, so check if it's cpu, dimm, UUID or
190 // BiosVer
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500191 for (const auto& connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700192 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500193 for (const auto& interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700194 {
Ed Tanous029573d2019-02-01 10:57:49 -0800195 if (interfaceName ==
196 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700197 {
Ed Tanous029573d2019-02-01 10:57:49 -0800198 BMCWEB_LOG_DEBUG
199 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500200
Ed Tanous029573d2019-02-01 10:57:49 -0800201 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500202 [aResp, service{connection.first},
203 path(std::move(path))](
204 const boost::system::error_code ec,
205 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500206 std::pair<std::string, VariantType>>&
207 properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800208 if (ec)
209 {
210 BMCWEB_LOG_ERROR
211 << "DBUS response error " << ec;
212 messages::internalError(aResp->res);
213 return;
214 }
215 BMCWEB_LOG_DEBUG << "Got "
216 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500217 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500218
219 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800220 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500221 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500222 VariantType>&
223 property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700224 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800225 if (property.first !=
226 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700227 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800228 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700229 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500230 const uint32_t* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500231 std::get_if<uint32_t>(
232 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800233 if (value == nullptr)
234 {
235 BMCWEB_LOG_DEBUG
236 << "Find incorrect type of "
237 "MemorySize";
238 continue;
239 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500240 nlohmann::json& totalMemory =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800241 aResp->res
242 .jsonValue["MemorySummar"
243 "y"]
244 ["TotalSystemMe"
245 "moryGiB"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500246 uint64_t* preValue =
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800247 totalMemory
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500248 .get_ptr<uint64_t*>();
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800249 if (preValue == nullptr)
250 {
251 continue;
252 }
253 aResp->res
254 .jsonValue["MemorySummary"]
255 ["TotalSystemMemoryGi"
256 "B"] =
257 *value / (1024 * 1024) +
258 *preValue;
259 aResp->res
260 .jsonValue["MemorySummary"]
261 ["Status"]["State"] =
262 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700263 }
Ed Tanous029573d2019-02-01 10:57:49 -0800264 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500265 else
266 {
267 auto getDimmProperties =
268 [aResp](
269 const boost::system::error_code
270 ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500271 const std::variant<bool>&
272 dimmState) {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500273 if (ec)
274 {
275 BMCWEB_LOG_ERROR
276 << "DBUS response "
277 "error "
278 << ec;
279 return;
280 }
281 updateDimmProperties(aResp,
282 dimmState);
283 };
284 crow::connections::systemBus
285 ->async_method_call(
286 std::move(getDimmProperties),
287 service, path,
288 "org.freedesktop.DBus."
289 "Properties",
290 "Get",
291 "xyz.openbmc_project.State."
292 "Decorator.OperationalStatus",
293 "Functional");
294 }
Ed Tanous029573d2019-02-01 10:57:49 -0800295 },
296 connection.first, path,
297 "org.freedesktop.DBus.Properties", "GetAll",
298 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700299
300 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800301 }
302 else if (interfaceName ==
303 "xyz.openbmc_project.Inventory.Item.Cpu")
304 {
305 BMCWEB_LOG_DEBUG
306 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500307
Ed Tanous029573d2019-02-01 10:57:49 -0800308 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500309 [aResp, service{connection.first},
310 path(std::move(path))](
311 const boost::system::error_code ec,
312 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500313 std::pair<std::string, VariantType>>&
314 properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800315 if (ec)
316 {
317 BMCWEB_LOG_ERROR
318 << "DBUS response error " << ec;
319 messages::internalError(aResp->res);
320 return;
321 }
322 BMCWEB_LOG_DEBUG << "Got "
323 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500324 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700325
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500326 if (properties.size() > 0)
327 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500328 for (const auto& property : properties)
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500329 {
330 if (property.first ==
331 "ProcessorFamily")
332 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500333 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500334 std::get_if<std::string>(
335 &property.second);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500336 if (value != nullptr)
337 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500338 nlohmann::json&
339 procSummary =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500340 aResp->res.jsonValue
341 ["ProcessorSumm"
342 "ary"];
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500343 nlohmann::json& procCount =
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500344 procSummary["Count"];
James Feistb4b95952019-12-05 15:01:55 -0800345
346 auto procCountPtr =
347 procCount.get_ptr<
348 nlohmann::json::
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500349 number_integer_t*>();
James Feistb4b95952019-12-05 15:01:55 -0800350 if (procCountPtr != nullptr)
351 {
352 // shouldn't be possible
353 // to be nullptr
354 *procCountPtr += 1;
355 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500356 procSummary["Status"]
357 ["State"] =
358 "Enabled";
359 procSummary["Model"] =
360 *value;
361 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700362 }
363 }
Ed Tanous029573d2019-02-01 10:57:49 -0800364 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500365 else
366 {
367 auto getCpuPresenceState =
368 [aResp](
369 const boost::system::error_code
370 ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500371 const std::variant<bool>&
372 cpuPresenceCheck) {
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500373 if (ec)
374 {
375 BMCWEB_LOG_ERROR
376 << "DBUS response "
377 "error "
378 << ec;
379 return;
380 }
381 modifyCpuPresenceState(
382 aResp, cpuPresenceCheck);
383 };
384
385 auto getCpuFunctionalState =
386 [aResp](
387 const boost::system::error_code
388 ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500389 const std::variant<bool>&
390 cpuFunctionalCheck) {
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500391 if (ec)
392 {
393 BMCWEB_LOG_ERROR
394 << "DBUS response "
395 "error "
396 << ec;
397 return;
398 }
399 modifyCpuFunctionalState(
400 aResp, cpuFunctionalCheck);
401 };
402 // Get the Presence of CPU
403 crow::connections::systemBus
404 ->async_method_call(
405 std::move(getCpuPresenceState),
406 service, path,
407 "org.freedesktop.DBus."
408 "Properties",
409 "Get",
410 "xyz.openbmc_project.Inventory."
411 "Item",
412 "Present");
413
414 // Get the Functional State
415 crow::connections::systemBus
416 ->async_method_call(
417 std::move(
418 getCpuFunctionalState),
419 service, path,
420 "org.freedesktop.DBus."
421 "Properties",
422 "Get",
423 "xyz.openbmc_project.State."
424 "Decorator."
425 "OperationalStatus",
426 "Functional");
427
428 // Get the MODEL from
429 // xyz.openbmc_project.Inventory.Decorator.Asset
430 // support it later as Model is Empty
431 // currently.
432 }
Ed Tanous029573d2019-02-01 10:57:49 -0800433 },
434 connection.first, path,
435 "org.freedesktop.DBus.Properties", "GetAll",
436 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700437
438 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800439 }
440 else if (interfaceName ==
441 "xyz.openbmc_project.Common.UUID")
442 {
443 BMCWEB_LOG_DEBUG
444 << "Found UUID, now get its properties.";
445 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500446 [aResp](
447 const boost::system::error_code ec,
448 const std::vector<
449 std::pair<std::string, VariantType>>&
450 properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800451 if (ec)
452 {
453 BMCWEB_LOG_DEBUG
454 << "DBUS response error " << ec;
455 messages::internalError(aResp->res);
456 return;
457 }
458 BMCWEB_LOG_DEBUG << "Got "
459 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500460 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800461 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500462 VariantType>&
463 property : properties)
Ed Tanous029573d2019-02-01 10:57:49 -0800464 {
Ed Tanous029573d2019-02-01 10:57:49 -0800465 if (property.first == "UUID")
466 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500467 const std::string* value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500468 std::get_if<std::string>(
469 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700470
Ed Tanous029573d2019-02-01 10:57:49 -0800471 if (value != nullptr)
472 {
473 std::string valueStr = *value;
474 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700475 {
Ed Tanous029573d2019-02-01 10:57:49 -0800476 valueStr.insert(8, 1, '-');
477 valueStr.insert(13, 1, '-');
478 valueStr.insert(18, 1, '-');
479 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700480 }
Ed Tanous029573d2019-02-01 10:57:49 -0800481 BMCWEB_LOG_DEBUG << "UUID = "
482 << valueStr;
483 aResp->res.jsonValue["UUID"] =
484 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700485 }
486 }
Ed Tanous029573d2019-02-01 10:57:49 -0800487 }
488 },
489 connection.first, path,
490 "org.freedesktop.DBus.Properties", "GetAll",
491 "xyz.openbmc_project.Common.UUID");
492 }
493 else if (interfaceName ==
494 "xyz.openbmc_project.Inventory.Item.System")
495 {
496 crow::connections::systemBus->async_method_call(
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500497 [aResp](
498 const boost::system::error_code ec,
499 const std::vector<
500 std::pair<std::string, VariantType>>&
501 propertiesList) {
Ed Tanous029573d2019-02-01 10:57:49 -0800502 if (ec)
503 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700504 // doesn't have to include this
505 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800506 return;
507 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500508 BMCWEB_LOG_DEBUG
509 << "Got " << propertiesList.size()
510 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800511 for (const std::pair<std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500512 VariantType>&
513 property : propertiesList)
Ed Tanous029573d2019-02-01 10:57:49 -0800514 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500515 const std::string& propertyName =
beccabroekfc5afcf2019-03-05 14:35:15 -0600516 property.first;
517 if ((propertyName == "PartNumber") ||
518 (propertyName == "SerialNumber") ||
519 (propertyName == "Manufacturer") ||
520 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800521 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500522 const std::string* value =
beccabroekfc5afcf2019-03-05 14:35:15 -0600523 std::get_if<std::string>(
524 &property.second);
525 if (value != nullptr)
526 {
527 aResp->res
528 .jsonValue[propertyName] =
529 *value;
530 }
Ed Tanous029573d2019-02-01 10:57:49 -0800531 }
532 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500533
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600534 // Grab the bios version
535 fw_util::getActiveFwVersion(
536 aResp, fw_util::biosPurpose,
537 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800538 },
539 connection.first, path,
540 "org.freedesktop.DBus.Properties", "GetAll",
541 "xyz.openbmc_project.Inventory.Decorator."
542 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700543
544 crow::connections::systemBus->async_method_call(
545 [aResp](
546 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500547 const std::variant<std::string>& property) {
James Feiste4a4b9a2019-06-20 14:08:07 -0700548 if (ec)
549 {
550 // doesn't have to include this
551 // interface
552 return;
553 }
554
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500555 const std::string* value =
James Feiste4a4b9a2019-06-20 14:08:07 -0700556 std::get_if<std::string>(&property);
557 if (value != nullptr)
558 {
559 aResp->res.jsonValue["AssetTag"] =
560 *value;
561 }
562 },
563 connection.first, path,
564 "org.freedesktop.DBus.Properties", "Get",
565 "xyz.openbmc_project.Inventory.Decorator."
566 "AssetTag",
567 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700568 }
569 }
570 }
571 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700572 },
573 "xyz.openbmc_project.ObjectMapper",
574 "/xyz/openbmc_project/object_mapper",
575 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700576 "/xyz/openbmc_project/inventory", int32_t(0),
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500577 std::array<const char*, 5>{
Ed Tanous66173382018-08-15 18:20:59 -0700578 "xyz.openbmc_project.Inventory.Decorator.Asset",
579 "xyz.openbmc_project.Inventory.Item.Cpu",
580 "xyz.openbmc_project.Inventory.Item.Dimm",
581 "xyz.openbmc_project.Inventory.Item.System",
582 "xyz.openbmc_project.Common.UUID",
583 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700584}
585
586/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700587 * @brief Retrieves host state properties over dbus
588 *
589 * @param[in] aResp Shared pointer for completing asynchronous calls.
590 *
591 * @return None.
592 */
593void getHostState(std::shared_ptr<AsyncResp> aResp)
594{
595 BMCWEB_LOG_DEBUG << "Get host information.";
596 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800597 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500598 const std::variant<std::string>& hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700599 if (ec)
600 {
601 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700602 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700603 return;
604 }
Ed Tanous66173382018-08-15 18:20:59 -0700605
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500606 const std::string* s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700607 BMCWEB_LOG_DEBUG << "Host state: " << *s;
608 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700609 {
Ed Tanous66173382018-08-15 18:20:59 -0700610 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800611 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700612 {
Ed Tanous66173382018-08-15 18:20:59 -0700613 aResp->res.jsonValue["PowerState"] = "On";
614 aResp->res.jsonValue["Status"]["State"] = "Enabled";
615 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600616 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500617 "Quiesced")
618 {
619 aResp->res.jsonValue["PowerState"] = "On";
620 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
621 }
622 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600623 "DiagnosticMode")
624 {
625 aResp->res.jsonValue["PowerState"] = "On";
626 aResp->res.jsonValue["Status"]["State"] = "InTest";
627 }
Ed Tanous66173382018-08-15 18:20:59 -0700628 else
629 {
630 aResp->res.jsonValue["PowerState"] = "Off";
631 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700632 }
633 }
634 },
635 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700636 "org.freedesktop.DBus.Properties", "Get",
637 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700638}
639
640/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500641 * @brief Translates boot source DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530642 *
643 * @param[in] dbusSource The boot source in DBUS speak.
644 *
645 * @return Returns as a string, the boot source in Redfish terms. If translation
646 * cannot be done, returns an empty string.
647 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500648static std::string dbusToRfBootSource(const std::string& dbusSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530649{
650 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
651 {
652 return "None";
653 }
654 else if (dbusSource ==
655 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
656 {
657 return "Hdd";
658 }
659 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530660 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530661 {
662 return "Cd";
663 }
664 else if (dbusSource ==
665 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
666 {
667 return "Pxe";
668 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700669 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700670 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700671 {
672 return "Usb";
673 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530674 else
675 {
676 return "";
677 }
678}
679
680/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500681 * @brief Translates boot mode DBUS property value to redfish.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530682 *
683 * @param[in] dbusMode The boot mode in DBUS speak.
684 *
685 * @return Returns as a string, the boot mode in Redfish terms. If translation
686 * cannot be done, returns an empty string.
687 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500688static std::string dbusToRfBootMode(const std::string& dbusMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530689{
690 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
691 {
692 return "None";
693 }
694 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
695 {
696 return "Diags";
697 }
698 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
699 {
700 return "BiosSetup";
701 }
702 else
703 {
704 return "";
705 }
706}
707
708/**
Gunnar Mills786d0f62020-07-08 13:43:15 -0500709 * @brief Translates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530710 *
711 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700712 * @param[out] bootSource The DBus source
713 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530714 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700715 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530716 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700717static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500718 const std::string& rfSource,
719 std::string& bootSource, std::string& bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530720{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700721 // The caller has initialized the bootSource and bootMode to:
722 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
723 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
724 // Only modify the bootSource/bootMode variable needed to achieve the
725 // desired boot action.
726
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530727 if (rfSource == "None")
728 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700729 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530730 }
731 else if (rfSource == "Pxe")
732 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700733 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
734 }
735 else if (rfSource == "Hdd")
736 {
737 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
738 }
739 else if (rfSource == "Diags")
740 {
741 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
742 }
743 else if (rfSource == "Cd")
744 {
745 bootSource =
746 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
747 }
748 else if (rfSource == "BiosSetup")
749 {
750 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530751 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700752 else if (rfSource == "Usb")
753 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700754 bootSource =
755 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700756 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530757 else
758 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700759 BMCWEB_LOG_DEBUG << "Invalid property value for "
760 "BootSourceOverrideTarget: "
761 << bootSource;
762 messages::propertyValueNotInList(aResp->res, rfSource,
763 "BootSourceTargetOverride");
764 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530765 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700766 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530767}
768
769/**
770 * @brief Retrieves boot mode over DBUS and fills out the response
771 *
772 * @param[in] aResp Shared pointer for generating response message.
773 * @param[in] bootDbusObj The dbus object to query for boot properties.
774 *
775 * @return None.
776 */
777static void getBootMode(std::shared_ptr<AsyncResp> aResp,
778 std::string bootDbusObj)
779{
780 crow::connections::systemBus->async_method_call(
781 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500782 const std::variant<std::string>& bootMode) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530783 if (ec)
784 {
785 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
786 messages::internalError(aResp->res);
787 return;
788 }
789
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500790 const std::string* bootModeStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530791 std::get_if<std::string>(&bootMode);
792
793 if (!bootModeStr)
794 {
795 messages::internalError(aResp->res);
796 return;
797 }
798
799 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
800
801 // TODO (Santosh): Do we need to support override mode?
802 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
803 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
804 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700805 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530806
807 if (*bootModeStr !=
808 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
809 {
810 auto rfMode = dbusToRfBootMode(*bootModeStr);
811 if (!rfMode.empty())
812 {
813 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
814 rfMode;
815 }
816 }
817
818 // If the BootSourceOverrideTarget is still "None" at the end,
819 // reset the BootSourceOverrideEnabled to indicate that
820 // overrides are disabled
821 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
822 "None")
823 {
824 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
825 "Disabled";
826 }
827 },
828 "xyz.openbmc_project.Settings", bootDbusObj,
829 "org.freedesktop.DBus.Properties", "Get",
830 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
831}
832
833/**
834 * @brief Retrieves boot source over DBUS
835 *
836 * @param[in] aResp Shared pointer for generating response message.
837 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
838 *
839 * @return None.
840 */
841static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
842{
843 std::string bootDbusObj =
844 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
845 : "/xyz/openbmc_project/control/host0/boot";
846
847 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
848 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
849 (oneTimeEnabled) ? "Once" : "Continuous";
850
851 crow::connections::systemBus->async_method_call(
852 [aResp, bootDbusObj](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500853 const std::variant<std::string>& bootSource) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530854 if (ec)
855 {
856 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
857 messages::internalError(aResp->res);
858 return;
859 }
860
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500861 const std::string* bootSourceStr =
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530862 std::get_if<std::string>(&bootSource);
863
864 if (!bootSourceStr)
865 {
866 messages::internalError(aResp->res);
867 return;
868 }
869 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
870
871 auto rfSource = dbusToRfBootSource(*bootSourceStr);
872 if (!rfSource.empty())
873 {
874 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
875 rfSource;
876 }
877 },
878 "xyz.openbmc_project.Settings", bootDbusObj,
879 "org.freedesktop.DBus.Properties", "Get",
880 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
881 getBootMode(std::move(aResp), std::move(bootDbusObj));
882}
883
884/**
885 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
886 * get boot source and boot mode.
887 *
888 * @param[in] aResp Shared pointer for generating response message.
889 *
890 * @return None.
891 */
892static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
893{
894 BMCWEB_LOG_DEBUG << "Get boot information.";
895
896 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800897 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500898 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530899 if (ec)
900 {
901 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700902 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530903 return;
904 }
905
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500906 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530907
908 if (!oneTimePtr)
909 {
910 messages::internalError(aResp->res);
911 return;
912 }
913 getBootSource(aResp, *oneTimePtr);
914 },
915 "xyz.openbmc_project.Settings",
916 "/xyz/openbmc_project/control/host0/boot/one_time",
917 "org.freedesktop.DBus.Properties", "Get",
918 "xyz.openbmc_project.Object.Enable", "Enabled");
919}
920
921/**
Gunnar Millsc0557e12020-06-30 11:26:20 -0500922 * @brief Retrieves the Last Reset Time
923 *
924 * "Reset" is an overloaded term in Redfish, "Reset" includes power on
925 * and power off. Even though this is the "system" Redfish object look at the
926 * chassis D-Bus interface for the LastStateChangeTime since this has the
927 * last power operation time.
928 *
929 * @param[in] aResp Shared pointer for generating response message.
930 *
931 * @return None.
932 */
933void getLastResetTime(std::shared_ptr<AsyncResp> aResp)
934{
935 BMCWEB_LOG_DEBUG << "Getting System Last Reset Time";
936
937 crow::connections::systemBus->async_method_call(
938 [aResp](const boost::system::error_code ec,
939 std::variant<uint64_t>& lastResetTime) {
940 if (ec)
941 {
942 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
943 return;
944 }
945
946 const uint64_t* lastResetTimePtr =
947 std::get_if<uint64_t>(&lastResetTime);
948
949 if (!lastResetTimePtr)
950 {
951 messages::internalError(aResp->res);
952 return;
953 }
954 // LastStateChangeTime is epoch time, in milliseconds
955 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/33e8e1dd64da53a66e888d33dc82001305cd0bf9/xyz/openbmc_project/State/Chassis.interface.yaml#L19
956 time_t lastResetTimeStamp =
957 static_cast<time_t>(*lastResetTimePtr / 1000);
958
959 // Convert to ISO 8601 standard
960 aResp->res.jsonValue["LastResetTime"] =
961 crow::utility::getDateTime(lastResetTimeStamp);
962 },
963 "xyz.openbmc_project.State.Chassis",
964 "/xyz/openbmc_project/state/chassis0",
965 "org.freedesktop.DBus.Properties", "Get",
966 "xyz.openbmc_project.State.Chassis", "LastStateChangeTime");
967}
968
969/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500970 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
971 *
972 * @param[in] aResp Shared pointer for generating response message.
973 *
974 * @return None.
975 */
976void getAutomaticRetry(std::shared_ptr<AsyncResp> aResp)
977{
978 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
979
980 crow::connections::systemBus->async_method_call(
981 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500982 std::variant<bool>& autoRebootEnabled) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500983 if (ec)
984 {
985 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
986 return;
987 }
988
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500989 const bool* autoRebootEnabledPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500990 std::get_if<bool>(&autoRebootEnabled);
991
992 if (!autoRebootEnabledPtr)
993 {
994 messages::internalError(aResp->res);
995 return;
996 }
997
998 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
999 if (*autoRebootEnabledPtr == true)
1000 {
1001 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1002 "RetryAttempts";
1003 // If AutomaticRetry (AutoReboot) is enabled see how many
1004 // attempts are left
1005 crow::connections::systemBus->async_method_call(
1006 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001007 std::variant<uint32_t>& autoRebootAttemptsLeft) {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001008 if (ec)
1009 {
1010 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
1011 return;
1012 }
1013
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001014 const uint32_t* autoRebootAttemptsLeftPtr =
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001015 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
1016
1017 if (!autoRebootAttemptsLeftPtr)
1018 {
1019 messages::internalError(aResp->res);
1020 return;
1021 }
1022
1023 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
1024 << *autoRebootAttemptsLeftPtr;
1025
1026 aResp->res
1027 .jsonValue["Boot"]
1028 ["RemainingAutomaticRetryAttempts"] =
1029 *autoRebootAttemptsLeftPtr;
1030 },
1031 "xyz.openbmc_project.State.Host",
1032 "/xyz/openbmc_project/state/host0",
1033 "org.freedesktop.DBus.Properties", "Get",
1034 "xyz.openbmc_project.Control.Boot.RebootAttempts",
1035 "AttemptsLeft");
1036 }
1037 else
1038 {
1039 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
1040 "Disabled";
1041 }
1042
1043 // Not on D-Bus. Hardcoded here:
1044 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
1045 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
Gunnar Mills69f35302020-05-17 16:06:31 -05001046
1047 // "AutomaticRetryConfig" can be 3 values, Disabled, RetryAlways,
1048 // and RetryAttempts. OpenBMC only supports Disabled and
1049 // RetryAttempts.
1050 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig@Redfish."
1051 "AllowableValues"] = {"Disabled",
1052 "RetryAttempts"};
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001053 },
1054 "xyz.openbmc_project.Settings",
1055 "/xyz/openbmc_project/control/host0/auto_reboot",
1056 "org.freedesktop.DBus.Properties", "Get",
1057 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1058}
1059
1060/**
George Liuc6a620f2020-04-10 17:18:11 +08001061 * @brief Retrieves power restore policy over DBUS.
1062 *
1063 * @param[in] aResp Shared pointer for generating response message.
1064 *
1065 * @return None.
1066 */
1067void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
1068{
1069 BMCWEB_LOG_DEBUG << "Get power restore policy";
1070
1071 crow::connections::systemBus->async_method_call(
1072 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001073 std::variant<std::string>& policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001074 if (ec)
1075 {
1076 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1077 return;
1078 }
1079
1080 const boost::container::flat_map<std::string, std::string>
1081 policyMaps = {
1082 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1083 "AlwaysOn",
1084 "AlwaysOn"},
1085 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1086 "AlwaysOff",
1087 "AlwaysOff"},
1088 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1089 "LastState",
1090 "LastState"}};
1091
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001092 const std::string* policyPtr = std::get_if<std::string>(&policy);
George Liuc6a620f2020-04-10 17:18:11 +08001093
1094 if (!policyPtr)
1095 {
1096 messages::internalError(aResp->res);
1097 return;
1098 }
1099
1100 auto policyMapsIt = policyMaps.find(*policyPtr);
1101 if (policyMapsIt == policyMaps.end())
1102 {
1103 messages::internalError(aResp->res);
1104 return;
1105 }
1106
1107 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1108 },
1109 "xyz.openbmc_project.Settings",
1110 "/xyz/openbmc_project/control/host0/power_restore_policy",
1111 "org.freedesktop.DBus.Properties", "Get",
1112 "xyz.openbmc_project.Control.Power.RestorePolicy",
1113 "PowerRestorePolicy");
1114}
1115
1116/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301117 * @brief Sets boot properties into DBUS object(s).
1118 *
1119 * @param[in] aResp Shared pointer for generating response message.
1120 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1121 * @param[in] bootSource The boot source to set.
1122 * @param[in] bootEnable The source override "enable" to set.
1123 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001124 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301125 */
1126static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1127 bool oneTimeEnabled,
1128 std::optional<std::string> bootSource,
1129 std::optional<std::string> bootEnable)
1130{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001131 std::string bootSourceStr =
1132 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1133 std::string bootModeStr =
1134 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301135 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001136 bool useBootSource = true;
1137
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301138 // Validate incoming parameters
1139 if (bootEnable)
1140 {
1141 if (*bootEnable == "Once")
1142 {
1143 oneTimeSetting = true;
1144 }
1145 else if (*bootEnable == "Continuous")
1146 {
1147 oneTimeSetting = false;
1148 }
1149 else if (*bootEnable == "Disabled")
1150 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001151 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301152 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001153 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301154 }
1155 else
1156 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301157 BMCWEB_LOG_DEBUG << "Unsupported value for "
1158 "BootSourceOverrideEnabled: "
1159 << *bootEnable;
1160 messages::propertyValueNotInList(aResp->res, *bootEnable,
1161 "BootSourceOverrideEnabled");
1162 return;
1163 }
1164 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301165
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001166 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301167 {
1168 // Source target specified
1169 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1170 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001171 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1172 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301173 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001174 BMCWEB_LOG_DEBUG
1175 << "Invalid property value for BootSourceOverrideTarget: "
1176 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301177 messages::propertyValueNotInList(aResp->res, *bootSource,
1178 "BootSourceTargetOverride");
1179 return;
1180 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001181 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301182
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001183 // Act on validated parameters
1184 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1185 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001186 const char* bootObj =
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001187 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1188 : "/xyz/openbmc_project/control/host0/boot";
1189
1190 crow::connections::systemBus->async_method_call(
1191 [aResp](const boost::system::error_code ec) {
1192 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301193 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001194 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1195 messages::internalError(aResp->res);
1196 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301197 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001198 BMCWEB_LOG_DEBUG << "Boot source update done.";
1199 },
1200 "xyz.openbmc_project.Settings", bootObj,
1201 "org.freedesktop.DBus.Properties", "Set",
1202 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1203 std::variant<std::string>(bootSourceStr));
1204
1205 crow::connections::systemBus->async_method_call(
1206 [aResp](const boost::system::error_code ec) {
1207 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301208 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001209 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1210 messages::internalError(aResp->res);
1211 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301212 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001213 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1214 },
1215 "xyz.openbmc_project.Settings", bootObj,
1216 "org.freedesktop.DBus.Properties", "Set",
1217 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1218 std::variant<std::string>(bootModeStr));
1219
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301220 crow::connections::systemBus->async_method_call(
1221 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1222 if (ec)
1223 {
1224 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1225 messages::internalError(aResp->res);
1226 return;
1227 }
1228 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1229 },
1230 "xyz.openbmc_project.Settings",
1231 "/xyz/openbmc_project/control/host0/boot/one_time",
1232 "org.freedesktop.DBus.Properties", "Set",
1233 "xyz.openbmc_project.Object.Enable", "Enabled",
1234 std::variant<bool>(oneTimeSetting));
1235}
1236
1237/**
1238 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1239 * set boot source/boot mode properties.
1240 *
1241 * @param[in] aResp Shared pointer for generating response message.
1242 * @param[in] bootSource The boot source from incoming RF request.
1243 * @param[in] bootEnable The boot override enable from incoming RF request.
1244 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001245 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301246 */
Gunnar Mills69f35302020-05-17 16:06:31 -05001247static void setBootSourceProperties(std::shared_ptr<AsyncResp> aResp,
1248 std::optional<std::string> bootSource,
1249 std::optional<std::string> bootEnable)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301250{
1251 BMCWEB_LOG_DEBUG << "Set boot information.";
1252
1253 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001254 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001255 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001256 const std::variant<bool>& oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301257 if (ec)
1258 {
1259 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1260 messages::internalError(aResp->res);
1261 return;
1262 }
1263
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001264 const bool* oneTimePtr = std::get_if<bool>(&oneTime);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301265
1266 if (!oneTimePtr)
1267 {
1268 messages::internalError(aResp->res);
1269 return;
1270 }
1271
1272 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1273
1274 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1275 std::move(bootEnable));
1276 },
1277 "xyz.openbmc_project.Settings",
1278 "/xyz/openbmc_project/control/host0/boot/one_time",
1279 "org.freedesktop.DBus.Properties", "Get",
1280 "xyz.openbmc_project.Object.Enable", "Enabled");
1281}
1282
George Liuc6a620f2020-04-10 17:18:11 +08001283/**
Gunnar Mills69f35302020-05-17 16:06:31 -05001284 * @brief Sets automaticRetry (Auto Reboot)
1285 *
1286 * @param[in] aResp Shared pointer for generating response message.
1287 * @param[in] automaticRetryConfig "AutomaticRetryConfig" from request.
1288 *
1289 * @return None.
1290 */
1291static void setAutomaticRetry(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001292 const std::string&& automaticRetryConfig)
Gunnar Mills69f35302020-05-17 16:06:31 -05001293{
1294 BMCWEB_LOG_DEBUG << "Set Automatic Retry.";
1295
1296 // OpenBMC only supports "Disabled" and "RetryAttempts".
1297 bool autoRebootEnabled;
1298
1299 if (automaticRetryConfig == "Disabled")
1300 {
1301 autoRebootEnabled = false;
1302 }
1303 else if (automaticRetryConfig == "RetryAttempts")
1304 {
1305 autoRebootEnabled = true;
1306 }
1307 else
1308 {
1309 BMCWEB_LOG_DEBUG << "Invalid property value for "
1310 "AutomaticRetryConfig: "
1311 << automaticRetryConfig;
1312 messages::propertyValueNotInList(aResp->res, automaticRetryConfig,
1313 "AutomaticRetryConfig");
1314 return;
1315 }
1316
1317 crow::connections::systemBus->async_method_call(
1318 [aResp](const boost::system::error_code ec) {
1319 if (ec)
1320 {
1321 messages::internalError(aResp->res);
1322 return;
1323 }
1324 },
1325 "xyz.openbmc_project.Settings",
1326 "/xyz/openbmc_project/control/host0/auto_reboot",
1327 "org.freedesktop.DBus.Properties", "Set",
1328 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot",
1329 std::variant<bool>(autoRebootEnabled));
1330}
1331
1332/**
George Liuc6a620f2020-04-10 17:18:11 +08001333 * @brief Sets power restore policy properties.
1334 *
1335 * @param[in] aResp Shared pointer for generating response message.
1336 * @param[in] policy power restore policy properties from request.
1337 *
1338 * @return None.
1339 */
1340static void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
1341 std::optional<std::string> policy)
1342{
1343 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1344
1345 const boost::container::flat_map<std::string, std::string> policyMaps = {
1346 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1347 "AlwaysOn"},
1348 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1349 "AlwaysOff"},
1350 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1351 "LastState"}};
1352
1353 std::string powerRestorPolicy;
1354
1355 auto policyMapsIt = policyMaps.find(*policy);
1356 if (policyMapsIt == policyMaps.end())
1357 {
1358 messages::internalError(aResp->res);
1359 return;
1360 }
1361
1362 powerRestorPolicy = policyMapsIt->second;
1363
1364 crow::connections::systemBus->async_method_call(
1365 [aResp](const boost::system::error_code ec) {
1366 if (ec)
1367 {
1368 messages::internalError(aResp->res);
1369 return;
1370 }
1371 },
1372 "xyz.openbmc_project.Settings",
1373 "/xyz/openbmc_project/control/host0/power_restore_policy",
1374 "org.freedesktop.DBus.Properties", "Set",
1375 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1376 std::variant<std::string>(powerRestorPolicy));
1377}
1378
AppaRao Pulia6349912019-10-18 17:16:08 +05301379#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1380/**
1381 * @brief Retrieves provisioning status
1382 *
1383 * @param[in] aResp Shared pointer for completing asynchronous calls.
1384 *
1385 * @return None.
1386 */
1387void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1388{
1389 BMCWEB_LOG_DEBUG << "Get OEM information.";
1390 crow::connections::systemBus->async_method_call(
1391 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001392 const std::vector<std::pair<std::string, VariantType>>&
1393 propertiesList) {
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301394 nlohmann::json& oemPFR =
1395 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
AppaRao Pulia6349912019-10-18 17:16:08 +05301396 if (ec)
1397 {
1398 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
AppaRao Pulib99fb1a2020-07-08 16:42:48 +05301399 // not an error, don't have to have the interface
1400 oemPFR["ProvisioningStatus"] = "NotProvisioned";
AppaRao Pulia6349912019-10-18 17:16:08 +05301401 return;
1402 }
1403
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001404 const bool* provState = nullptr;
1405 const bool* lockState = nullptr;
1406 for (const std::pair<std::string, VariantType>& property :
AppaRao Pulia6349912019-10-18 17:16:08 +05301407 propertiesList)
1408 {
1409 if (property.first == "UfmProvisioned")
1410 {
1411 provState = std::get_if<bool>(&property.second);
1412 }
1413 else if (property.first == "UfmLocked")
1414 {
1415 lockState = std::get_if<bool>(&property.second);
1416 }
1417 }
1418
1419 if ((provState == nullptr) || (lockState == nullptr))
1420 {
1421 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1422 messages::internalError(aResp->res);
1423 return;
1424 }
1425
AppaRao Pulia6349912019-10-18 17:16:08 +05301426 if (*provState == true)
1427 {
1428 if (*lockState == true)
1429 {
1430 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1431 }
1432 else
1433 {
1434 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1435 }
1436 }
1437 else
1438 {
1439 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1440 }
1441 },
1442 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1443 "org.freedesktop.DBus.Properties", "GetAll",
1444 "xyz.openbmc_project.PFR.Attributes");
1445}
1446#endif
1447
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301448/**
Yong Li51709ff2019-09-30 14:13:04 +08001449 * @brief Translates watchdog timeout action DBUS property value to redfish.
1450 *
1451 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1452 *
1453 * @return Returns as a string, the timeout action in Redfish terms. If
1454 * translation cannot be done, returns an empty string.
1455 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001456static std::string dbusToRfWatchdogAction(const std::string& dbusAction)
Yong Li51709ff2019-09-30 14:13:04 +08001457{
1458 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1459 {
1460 return "None";
1461 }
1462 else if (dbusAction ==
1463 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1464 {
1465 return "ResetSystem";
1466 }
1467 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1468 {
1469 return "PowerDown";
1470 }
1471 else if (dbusAction ==
1472 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1473 {
1474 return "PowerCycle";
1475 }
1476
1477 return "";
1478}
1479
1480/**
Yong Lic45f0082019-10-10 14:19:01 +08001481 *@brief Translates timeout action from Redfish to DBUS property value.
1482 *
1483 *@param[in] rfAction The timeout action in Redfish.
1484 *
1485 *@return Returns as a string, the time_out action as expected by DBUS.
1486 *If translation cannot be done, returns an empty string.
1487 */
1488
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001489static std::string rfToDbusWDTTimeOutAct(const std::string& rfAction)
Yong Lic45f0082019-10-10 14:19:01 +08001490{
1491 if (rfAction == "None")
1492 {
1493 return "xyz.openbmc_project.State.Watchdog.Action.None";
1494 }
1495 else if (rfAction == "PowerCycle")
1496 {
1497 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1498 }
1499 else if (rfAction == "PowerDown")
1500 {
1501 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1502 }
1503 else if (rfAction == "ResetSystem")
1504 {
1505 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1506 }
1507
1508 return "";
1509}
1510
1511/**
Yong Li51709ff2019-09-30 14:13:04 +08001512 * @brief Retrieves host watchdog timer properties over DBUS
1513 *
1514 * @param[in] aResp Shared pointer for completing asynchronous calls.
1515 *
1516 * @return None.
1517 */
1518void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1519{
1520 BMCWEB_LOG_DEBUG << "Get host watchodg";
1521 crow::connections::systemBus->async_method_call(
1522 [aResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001523 PropertiesType& properties) {
Yong Li51709ff2019-09-30 14:13:04 +08001524 if (ec)
1525 {
1526 // watchdog service is stopped
1527 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1528 return;
1529 }
1530
1531 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1532
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001533 nlohmann::json& hostWatchdogTimer =
Yong Li51709ff2019-09-30 14:13:04 +08001534 aResp->res.jsonValue["HostWatchdogTimer"];
1535
1536 // watchdog service is running/enabled
1537 hostWatchdogTimer["Status"]["State"] = "Enabled";
1538
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001539 for (const auto& property : properties)
Yong Li51709ff2019-09-30 14:13:04 +08001540 {
1541 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1542 if (property.first == "Enabled")
1543 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001544 const bool* state = std::get_if<bool>(&property.second);
Yong Li51709ff2019-09-30 14:13:04 +08001545
1546 if (!state)
1547 {
1548 messages::internalError(aResp->res);
1549 continue;
1550 }
1551
1552 hostWatchdogTimer["FunctionEnabled"] = *state;
1553 }
1554 else if (property.first == "ExpireAction")
1555 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001556 const std::string* s =
Yong Li51709ff2019-09-30 14:13:04 +08001557 std::get_if<std::string>(&property.second);
1558 if (!s)
1559 {
1560 messages::internalError(aResp->res);
1561 continue;
1562 }
1563
1564 std::string action = dbusToRfWatchdogAction(*s);
1565 if (action.empty())
1566 {
1567 messages::internalError(aResp->res);
1568 continue;
1569 }
1570 hostWatchdogTimer["TimeoutAction"] = action;
1571 }
1572 }
1573 },
1574 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1575 "org.freedesktop.DBus.Properties", "GetAll",
1576 "xyz.openbmc_project.State.Watchdog");
1577}
1578
1579/**
Yong Lic45f0082019-10-10 14:19:01 +08001580 * @brief Sets Host WatchDog Timer properties.
1581 *
1582 * @param[in] aResp Shared pointer for generating response message.
1583 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1584 * RF request.
1585 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1586 *
1587 * @return None.
1588 */
1589static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1590 const std::optional<bool> wdtEnable,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001591 const std::optional<std::string>& wdtTimeOutAction)
Yong Lic45f0082019-10-10 14:19:01 +08001592{
1593 BMCWEB_LOG_DEBUG << "Set host watchdog";
1594
1595 if (wdtTimeOutAction)
1596 {
1597 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1598 // check if TimeOut Action is Valid
1599 if (wdtTimeOutActStr.empty())
1600 {
1601 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1602 << *wdtTimeOutAction;
1603 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1604 "TimeoutAction");
1605 return;
1606 }
1607
1608 crow::connections::systemBus->async_method_call(
1609 [aResp](const boost::system::error_code ec) {
1610 if (ec)
1611 {
1612 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1613 messages::internalError(aResp->res);
1614 return;
1615 }
1616 },
1617 "xyz.openbmc_project.Watchdog",
1618 "/xyz/openbmc_project/watchdog/host0",
1619 "org.freedesktop.DBus.Properties", "Set",
1620 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1621 std::variant<std::string>(wdtTimeOutActStr));
1622 }
1623
1624 if (wdtEnable)
1625 {
1626 crow::connections::systemBus->async_method_call(
1627 [aResp](const boost::system::error_code ec) {
1628 if (ec)
1629 {
1630 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1631 messages::internalError(aResp->res);
1632 return;
1633 }
1634 },
1635 "xyz.openbmc_project.Watchdog",
1636 "/xyz/openbmc_project/watchdog/host0",
1637 "org.freedesktop.DBus.Properties", "Set",
1638 "xyz.openbmc_project.State.Watchdog", "Enabled",
1639 std::variant<bool>(*wdtEnable));
1640 }
1641}
1642
1643/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001644 * SystemsCollection derived class for delivering ComputerSystems Collection
1645 * Schema
1646 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001647class SystemsCollection : public Node
1648{
1649 public:
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001650 SystemsCollection(CrowApp& app) : Node(app, "/redfish/v1/Systems/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001651 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001652 entityPrivileges = {
1653 {boost::beast::http::verb::get, {{"Login"}}},
1654 {boost::beast::http::verb::head, {{"Login"}}},
1655 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1656 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1657 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1658 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1659 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001660
Ed Tanous1abe55e2018-09-05 08:30:59 -07001661 private:
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001662 void doGet(crow::Response& res, const crow::Request& req,
1663 const std::vector<std::string>& params) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001664 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001665 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001666 res.jsonValue["@odata.type"] =
1667 "#ComputerSystemCollection.ComputerSystemCollection";
1668 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001669 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001670
1671 crow::connections::systemBus->async_method_call(
1672 [asyncResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001673 const std::variant<std::string>& hostName) {
1674 nlohmann::json& iface_array =
Sunitha Harish462023a2020-02-19 08:34:59 -06001675 asyncResp->res.jsonValue["Members"];
1676 iface_array = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001677 auto& count = asyncResp->res.jsonValue["Members@odata.count"];
Sunitha Harish462023a2020-02-19 08:34:59 -06001678 count = 0;
1679 if (ec)
1680 {
1681 iface_array.push_back(
1682 {{"@odata.id", "/redfish/v1/Systems/system"}});
1683 count = iface_array.size();
1684 return;
1685 }
1686 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1687 iface_array.push_back(
1688 {{"@odata.id", "/redfish/v1/Systems/system"}});
1689 iface_array.push_back(
1690 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1691 count = iface_array.size();
1692 },
Sunitha Harish8e651fb2020-06-17 06:06:25 -05001693 "xyz.openbmc_project.Settings",
1694 "/xyz/openbmc_project/network/hypervisor",
Sunitha Harish462023a2020-02-19 08:34:59 -06001695 "org.freedesktop.DBus.Properties", "Get",
1696 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001697 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001698};
1699
1700/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001701 * SystemActionsReset class supports handle POST method for Reset action.
1702 * The class retrieves and sends data directly to D-Bus.
1703 */
1704class SystemActionsReset : public Node
1705{
1706 public:
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001707 SystemActionsReset(CrowApp& app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001708 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001709 {
1710 entityPrivileges = {
1711 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1712 }
1713
1714 private:
1715 /**
1716 * Function handles POST method request.
1717 * Analyzes POST body message before sends Reset request data to D-Bus.
1718 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001719 void doPost(crow::Response& res, const crow::Request& req,
1720 const std::vector<std::string>& params) override
Ed Tanouscc340dd2018-08-29 13:43:38 -07001721 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001722 auto asyncResp = std::make_shared<AsyncResp>(res);
1723
1724 std::string resetType;
1725 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001726 {
1727 return;
1728 }
1729
Jason M. Billsd22c8392019-06-03 13:59:03 -07001730 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001731 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001732 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001733 if (resetType == "On")
1734 {
1735 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001736 hostCommand = true;
1737 }
1738 else if (resetType == "ForceOff")
1739 {
1740 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1741 hostCommand = false;
1742 }
1743 else if (resetType == "ForceOn")
1744 {
1745 command = "xyz.openbmc_project.State.Host.Transition.On";
1746 hostCommand = true;
1747 }
1748 else if (resetType == "ForceRestart")
1749 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001750 command =
1751 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1752 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001753 }
1754 else if (resetType == "GracefulShutdown")
1755 {
1756 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001757 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001758 }
1759 else if (resetType == "GracefulRestart")
1760 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001761 command =
1762 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001763 hostCommand = true;
1764 }
1765 else if (resetType == "PowerCycle")
1766 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001767 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1768 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001769 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001770 else if (resetType == "Nmi")
1771 {
1772 doNMI(asyncResp);
1773 return;
1774 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001775 else
1776 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001777 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001778 return;
1779 }
1780
Jason M. Billsd22c8392019-06-03 13:59:03 -07001781 if (hostCommand)
1782 {
1783 crow::connections::systemBus->async_method_call(
1784 [asyncResp, resetType](const boost::system::error_code ec) {
1785 if (ec)
1786 {
1787 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1788 if (ec.value() == boost::asio::error::invalid_argument)
1789 {
1790 messages::actionParameterNotSupported(
1791 asyncResp->res, resetType, "Reset");
1792 }
1793 else
1794 {
1795 messages::internalError(asyncResp->res);
1796 }
1797 return;
1798 }
1799 messages::success(asyncResp->res);
1800 },
1801 "xyz.openbmc_project.State.Host",
1802 "/xyz/openbmc_project/state/host0",
1803 "org.freedesktop.DBus.Properties", "Set",
1804 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1805 std::variant<std::string>{command});
1806 }
1807 else
1808 {
1809 crow::connections::systemBus->async_method_call(
1810 [asyncResp, resetType](const boost::system::error_code ec) {
1811 if (ec)
1812 {
1813 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1814 if (ec.value() == boost::asio::error::invalid_argument)
1815 {
1816 messages::actionParameterNotSupported(
1817 asyncResp->res, resetType, "Reset");
1818 }
1819 else
1820 {
1821 messages::internalError(asyncResp->res);
1822 }
1823 return;
1824 }
1825 messages::success(asyncResp->res);
1826 },
1827 "xyz.openbmc_project.State.Chassis",
1828 "/xyz/openbmc_project/state/chassis0",
1829 "org.freedesktop.DBus.Properties", "Set",
1830 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1831 std::variant<std::string>{command});
1832 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001833 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001834 /**
1835 * Function transceives data with dbus directly.
1836 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001837 void doNMI(const std::shared_ptr<AsyncResp>& asyncResp)
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001838 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001839 constexpr char const* serviceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001840 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001841 constexpr char const* objectPath =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001842 "/xyz/openbmc_project/control/host0/nmi";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001843 constexpr char const* interfaceName =
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001844 "xyz.openbmc_project.Control.Host.NMI";
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001845 constexpr char const* method = "NMI";
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001846
1847 crow::connections::systemBus->async_method_call(
1848 [asyncResp](const boost::system::error_code ec) {
1849 if (ec)
1850 {
1851 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1852 messages::internalError(asyncResp->res);
1853 return;
1854 }
1855 messages::success(asyncResp->res);
1856 },
1857 serviceName, objectPath, interfaceName, method);
1858 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001859};
1860
1861/**
Ed Tanous66173382018-08-15 18:20:59 -07001862 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001863 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001864class Systems : public Node
1865{
1866 public:
1867 /*
1868 * Default Constructor
1869 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001870 Systems(CrowApp& app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001871 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001872 entityPrivileges = {
1873 {boost::beast::http::verb::get, {{"Login"}}},
1874 {boost::beast::http::verb::head, {{"Login"}}},
1875 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1876 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1877 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1878 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001879 }
1880
Ed Tanous1abe55e2018-09-05 08:30:59 -07001881 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001882 /**
1883 * Functions triggers appropriate requests on DBus
1884 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001885 void doGet(crow::Response& res, const crow::Request& req,
1886 const std::vector<std::string>& params) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001887 {
Gunnar Millsc0557e12020-06-30 11:26:20 -05001888 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_12_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001889 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001890 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001891 res.jsonValue["SystemType"] = "Physical";
1892 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001893 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1894 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001895 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001896 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001897 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001898
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001899 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001900 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001901 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001902 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001903 res.jsonValue["Storage"] = {
1904 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001905
Ed Tanouscc340dd2018-08-29 13:43:38 -07001906 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1907 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001908 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001909 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001910 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001911 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001912
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001913 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001914 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001915
Carol Wangd82a3ac2019-11-21 13:56:38 +08001916 res.jsonValue["Bios"] = {
1917 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1918
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001919 res.jsonValue["Links"]["ManagedBy"] = {
1920 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1921
1922 res.jsonValue["Status"] = {
1923 {"Health", "OK"},
1924 {"State", "Enabled"},
1925 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001926 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001927
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001928 constexpr const std::array<const char*, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001929 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001930 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001931 "xyz.openbmc_project.Inventory.Item.Drive",
1932 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001933
1934 auto health = std::make_shared<HealthPopulate>(asyncResp);
1935 crow::connections::systemBus->async_method_call(
1936 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001937 std::vector<std::string>& resp) {
James Feistb49ac872019-05-21 15:12:01 -07001938 if (ec)
1939 {
1940 // no inventory
1941 return;
1942 }
1943
1944 health->inventory = std::move(resp);
1945 },
1946 "xyz.openbmc_project.ObjectMapper",
1947 "/xyz/openbmc_project/object_mapper",
1948 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1949 int32_t(0), inventoryForSystems);
1950
1951 health->populate();
1952
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001953 getMainChassisId(asyncResp, [](const std::string& chassisId,
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001954 std::shared_ptr<AsyncResp> aRsp) {
1955 aRsp->res.jsonValue["Links"]["Chassis"] = {
1956 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1957 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301958
1959 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001960 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001961 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301962 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001963 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001964 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001965 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001966 getAutomaticRetry(asyncResp);
Gunnar Millsc0557e12020-06-30 11:26:20 -05001967 getLastResetTime(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301968#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1969 getProvisioningStatus(asyncResp);
1970#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001971 }
1972
Gunnar Mills1214b7e2020-06-04 10:11:30 -05001973 void doPatch(crow::Response& res, const crow::Request& req,
1974 const std::vector<std::string>& params) override
Ed Tanous1abe55e2018-09-05 08:30:59 -07001975 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301976 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301977 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001978 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001979 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001980 auto asyncResp = std::make_shared<AsyncResp>(res);
1981
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001982 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001983 bootProps, "WatchdogTimer", wdtTimerProps,
1984 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001985 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001986 return;
1987 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301988
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001989 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001990
1991 if (wdtTimerProps)
1992 {
1993 std::optional<bool> wdtEnable;
1994 std::optional<std::string> wdtTimeOutAction;
1995
1996 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1997 "FunctionEnabled", wdtEnable,
1998 "TimeoutAction", wdtTimeOutAction))
1999 {
2000 return;
2001 }
2002 setWDTProperties(asyncResp, std::move(wdtEnable),
2003 std::move(wdtTimeOutAction));
2004 }
2005
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302006 if (bootProps)
2007 {
2008 std::optional<std::string> bootSource;
2009 std::optional<std::string> bootEnable;
Gunnar Mills69f35302020-05-17 16:06:31 -05002010 std::optional<std::string> automaticRetryConfig;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302011
Gunnar Mills69f35302020-05-17 16:06:31 -05002012 if (!json_util::readJson(
2013 *bootProps, asyncResp->res, "BootSourceOverrideTarget",
2014 bootSource, "BootSourceOverrideEnabled", bootEnable,
2015 "AutomaticRetryConfig", automaticRetryConfig))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302016 {
2017 return;
2018 }
Gunnar Mills69f35302020-05-17 16:06:31 -05002019 if (bootSource || bootEnable)
2020 {
2021 setBootSourceProperties(asyncResp, std::move(bootSource),
2022 std::move(bootEnable));
2023 }
2024 if (automaticRetryConfig)
2025 {
2026 setAutomaticRetry(asyncResp, std::move(*automaticRetryConfig));
2027 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05302028 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07002029
Ed Tanous9712f8a2018-09-21 13:38:49 -07002030 if (indicatorLed)
2031 {
AppaRao Pulia3002222019-11-12 21:32:59 +05302032 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07002033 }
George Liuc6a620f2020-04-10 17:18:11 +08002034
2035 if (powerRestorePolicy)
2036 {
2037 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
2038 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002039 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02002040};
Ed Tanous1abe55e2018-09-05 08:30:59 -07002041} // namespace redfish