blob: 81f310782a65e9b39b28fecacb7ea231d6cdf4ef [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>
Ed Tanousabf2add2019-01-22 16:40:12 -080027#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020028
Ed Tanous1abe55e2018-09-05 08:30:59 -070029namespace redfish
30{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020031
Alpana Kumari9d3ae102019-04-12 06:49:32 -050032/**
33 * @brief Updates the Functional State of DIMMs
34 *
35 * @param[in] aResp Shared pointer for completing asynchronous calls
36 * @param[in] dimmState Dimm's Functional state, true/false
37 *
38 * @return None.
39 */
40void updateDimmProperties(std::shared_ptr<AsyncResp> aResp,
41 const std::variant<bool> &dimmState)
42{
43 const bool *isDimmFunctional = std::get_if<bool>(&dimmState);
44 if (isDimmFunctional == nullptr)
45 {
46 messages::internalError(aResp->res);
47 return;
48 }
Gunnar Mills698654b2019-10-16 13:17:37 -050049 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050050
51 // Set it as Enabled if atleast one DIMM is functional
52 // Update STATE only if previous State was DISABLED and current Dimm is
53 // ENABLED.
54 nlohmann::json &prevMemSummary =
55 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
56 if (prevMemSummary == "Disabled")
57 {
58 if (*isDimmFunctional == true)
59 {
60 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
61 "Enabled";
62 }
63 }
64}
65
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050066/*
67 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
68 *
69 * @param[in] aResp Shared pointer for completing asynchronous calls
70 * @param[in] cpuPresenceState CPU present or not
71 *
72 * @return None.
73 */
74void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
75 const std::variant<bool> &cpuPresenceState)
76{
77 const bool *isCpuPresent = std::get_if<bool>(&cpuPresenceState);
78
79 if (isCpuPresent == nullptr)
80 {
81 messages::internalError(aResp->res);
82 return;
83 }
Gunnar Mills698654b2019-10-16 13:17:37 -050084 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050085
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050086 if (*isCpuPresent == true)
87 {
James Feistb4b95952019-12-05 15:01:55 -080088 nlohmann::json &procCount =
89 aResp->res.jsonValue["ProcessorSummary"]["Count"];
90 auto procCountPtr =
91 procCount.get_ptr<nlohmann::json::number_integer_t *>();
92 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 */
109void modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
110 const std::variant<bool> &cpuFunctionalState)
111{
112 const bool *isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
113
114 if (isCpuFunctional == nullptr)
115 {
116 messages::internalError(aResp->res);
117 return;
118 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500119 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500120
121 nlohmann::json &prevProcState =
122 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
123
124 // Set it as Enabled if atleast one CPU is functional
125 // Update STATE only if previous State was Non_Functional and current CPU is
126 // Functional.
127 if (prevProcState == "Disabled")
128 {
129 if (*isCpuFunctional == true)
130 {
131 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
132 "Enabled";
133 }
134 }
135}
136
137/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700138 * @brief Retrieves computer system properties over dbus
139 *
140 * @param[in] aResp Shared pointer for completing asynchronous calls
141 * @param[in] name Computer system name from request
142 *
143 * @return None.
144 */
James Feist5bc2dc82019-10-22 14:33:16 -0700145void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
146 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700147{
Ed Tanous6c34de42018-08-29 13:37:36 -0700148 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500149
Ed Tanous6c34de42018-08-29 13:37:36 -0700150 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700151 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700152 const boost::system::error_code ec,
153 const std::vector<std::pair<
154 std::string,
155 std::vector<std::pair<std::string, std::vector<std::string>>>>>
156 &subtree) {
157 if (ec)
158 {
159 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700160 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700161 return;
162 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700163 // Iterate over all retrieved ObjectPaths.
164 for (const std::pair<std::string,
165 std::vector<std::pair<
166 std::string, std::vector<std::string>>>>
167 &object : subtree)
168 {
169 const std::string &path = object.first;
170 BMCWEB_LOG_DEBUG << "Got path: " << path;
171 const std::vector<
172 std::pair<std::string, std::vector<std::string>>>
173 &connectionNames = object.second;
174 if (connectionNames.size() < 1)
175 {
176 continue;
177 }
Ed Tanous029573d2019-02-01 10:57:49 -0800178
James Feist5bc2dc82019-10-22 14:33:16 -0700179 auto memoryHealth = std::make_shared<HealthPopulate>(
180 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
181
182 auto cpuHealth = std::make_shared<HealthPopulate>(
183 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
184
185 systemHealth->children.emplace_back(memoryHealth);
186 systemHealth->children.emplace_back(cpuHealth);
187
Ed Tanous029573d2019-02-01 10:57:49 -0800188 // This is not system, so check if it's cpu, dimm, UUID or
189 // BiosVer
190 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700191 {
Ed Tanous029573d2019-02-01 10:57:49 -0800192 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700193 {
Ed Tanous029573d2019-02-01 10:57:49 -0800194 if (interfaceName ==
195 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700196 {
Ed Tanous029573d2019-02-01 10:57:49 -0800197 BMCWEB_LOG_DEBUG
198 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500199
Ed Tanous029573d2019-02-01 10:57:49 -0800200 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500201 [aResp, service{connection.first},
202 path(std::move(path))](
203 const boost::system::error_code ec,
204 const std::vector<
205 std::pair<std::string, VariantType>>
206 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800207 if (ec)
208 {
209 BMCWEB_LOG_ERROR
210 << "DBUS response error " << ec;
211 messages::internalError(aResp->res);
212 return;
213 }
214 BMCWEB_LOG_DEBUG << "Got "
215 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500216 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500217
218 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800219 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500220 for (const std::pair<std::string,
221 VariantType>
222 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700223 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800224 if (property.first !=
225 "MemorySizeInKB")
Ed Tanous6c34de42018-08-29 13:37:36 -0700226 {
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800227 continue;
Ed Tanous6c34de42018-08-29 13:37:36 -0700228 }
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800229 const uint32_t *value =
230 sdbusplus::message::variant_ns::
231 get_if<uint32_t>(
232 &property.second);
233 if (value == nullptr)
234 {
235 BMCWEB_LOG_DEBUG
236 << "Find incorrect type of "
237 "MemorySize";
238 continue;
239 }
240 nlohmann::json &totalMemory =
241 aResp->res
242 .jsonValue["MemorySummar"
243 "y"]
244 ["TotalSystemMe"
245 "moryGiB"];
246 uint64_t *preValue =
247 totalMemory
248 .get_ptr<uint64_t *>();
249 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,
271 const std::variant<bool>
272 &dimmState) {
273 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<
313 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 {
328 for (const auto &property : properties)
329 {
330 if (property.first ==
331 "ProcessorFamily")
332 {
333 const std::string *value =
334 sdbusplus::message::
335 variant_ns::get_if<
336 std::string>(
337 &property.second);
338 if (value != nullptr)
339 {
340 nlohmann::json
341 &procSummary =
342 aResp->res.jsonValue
343 ["ProcessorSumm"
344 "ary"];
345 nlohmann::json &procCount =
346 procSummary["Count"];
James Feistb4b95952019-12-05 15:01:55 -0800347
348 auto procCountPtr =
349 procCount.get_ptr<
350 nlohmann::json::
351 number_integer_t
352 *>();
353 if (procCountPtr != nullptr)
354 {
355 // shouldn't be possible
356 // to be nullptr
357 *procCountPtr += 1;
358 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500359 procSummary["Status"]
360 ["State"] =
361 "Enabled";
362 procSummary["Model"] =
363 *value;
364 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700365 }
366 }
Ed Tanous029573d2019-02-01 10:57:49 -0800367 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500368 else
369 {
370 auto getCpuPresenceState =
371 [aResp](
372 const boost::system::error_code
373 ec,
374 const std::variant<bool>
375 &cpuPresenceCheck) {
376 if (ec)
377 {
378 BMCWEB_LOG_ERROR
379 << "DBUS response "
380 "error "
381 << ec;
382 return;
383 }
384 modifyCpuPresenceState(
385 aResp, cpuPresenceCheck);
386 };
387
388 auto getCpuFunctionalState =
389 [aResp](
390 const boost::system::error_code
391 ec,
392 const std::variant<bool>
393 &cpuFunctionalCheck) {
394 if (ec)
395 {
396 BMCWEB_LOG_ERROR
397 << "DBUS response "
398 "error "
399 << ec;
400 return;
401 }
402 modifyCpuFunctionalState(
403 aResp, cpuFunctionalCheck);
404 };
405 // Get the Presence of CPU
406 crow::connections::systemBus
407 ->async_method_call(
408 std::move(getCpuPresenceState),
409 service, path,
410 "org.freedesktop.DBus."
411 "Properties",
412 "Get",
413 "xyz.openbmc_project.Inventory."
414 "Item",
415 "Present");
416
417 // Get the Functional State
418 crow::connections::systemBus
419 ->async_method_call(
420 std::move(
421 getCpuFunctionalState),
422 service, path,
423 "org.freedesktop.DBus."
424 "Properties",
425 "Get",
426 "xyz.openbmc_project.State."
427 "Decorator."
428 "OperationalStatus",
429 "Functional");
430
431 // Get the MODEL from
432 // xyz.openbmc_project.Inventory.Decorator.Asset
433 // support it later as Model is Empty
434 // currently.
435 }
Ed Tanous029573d2019-02-01 10:57:49 -0800436 },
437 connection.first, path,
438 "org.freedesktop.DBus.Properties", "GetAll",
439 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700440
441 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800442 }
443 else if (interfaceName ==
444 "xyz.openbmc_project.Common.UUID")
445 {
446 BMCWEB_LOG_DEBUG
447 << "Found UUID, now get its properties.";
448 crow::connections::systemBus->async_method_call(
449 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700450 const std::vector<
451 std::pair<std::string, VariantType>>
452 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800453 if (ec)
454 {
455 BMCWEB_LOG_DEBUG
456 << "DBUS response error " << ec;
457 messages::internalError(aResp->res);
458 return;
459 }
460 BMCWEB_LOG_DEBUG << "Got "
461 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500462 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800463 for (const std::pair<std::string,
464 VariantType>
465 &property : properties)
466 {
Ed Tanous029573d2019-02-01 10:57:49 -0800467 if (property.first == "UUID")
468 {
469 const std::string *value =
470 sdbusplus::message::variant_ns::
471 get_if<std::string>(
472 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700473
Ed Tanous029573d2019-02-01 10:57:49 -0800474 if (value != nullptr)
475 {
476 std::string valueStr = *value;
477 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700478 {
Ed Tanous029573d2019-02-01 10:57:49 -0800479 valueStr.insert(8, 1, '-');
480 valueStr.insert(13, 1, '-');
481 valueStr.insert(18, 1, '-');
482 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700483 }
Ed Tanous029573d2019-02-01 10:57:49 -0800484 BMCWEB_LOG_DEBUG << "UUID = "
485 << valueStr;
486 aResp->res.jsonValue["UUID"] =
487 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700488 }
489 }
Ed Tanous029573d2019-02-01 10:57:49 -0800490 }
491 },
492 connection.first, path,
493 "org.freedesktop.DBus.Properties", "GetAll",
494 "xyz.openbmc_project.Common.UUID");
495 }
496 else if (interfaceName ==
497 "xyz.openbmc_project.Inventory.Item.System")
498 {
499 crow::connections::systemBus->async_method_call(
500 [aResp](const boost::system::error_code ec,
501 const std::vector<
502 std::pair<std::string, VariantType>>
503 &propertiesList) {
504 if (ec)
505 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700506 // doesn't have to include this
507 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800508 return;
509 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500510 BMCWEB_LOG_DEBUG
511 << "Got " << propertiesList.size()
512 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800513 for (const std::pair<std::string,
514 VariantType>
515 &property : propertiesList)
516 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600517 const std::string &propertyName =
518 property.first;
519 if ((propertyName == "PartNumber") ||
520 (propertyName == "SerialNumber") ||
521 (propertyName == "Manufacturer") ||
522 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800523 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600524 const std::string *value =
525 std::get_if<std::string>(
526 &property.second);
527 if (value != nullptr)
528 {
529 aResp->res
530 .jsonValue[propertyName] =
531 *value;
532 }
Ed Tanous029573d2019-02-01 10:57:49 -0800533 }
534 }
Ed Tanous029573d2019-02-01 10:57:49 -0800535 aResp->res.jsonValue["Id"] =
536 aResp->res.jsonValue["SerialNumber"];
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600537 // Grab the bios version
538 fw_util::getActiveFwVersion(
539 aResp, fw_util::biosPurpose,
540 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800541 },
542 connection.first, path,
543 "org.freedesktop.DBus.Properties", "GetAll",
544 "xyz.openbmc_project.Inventory.Decorator."
545 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700546
547 crow::connections::systemBus->async_method_call(
548 [aResp](
549 const boost::system::error_code ec,
550 const std::variant<std::string> &property) {
551 if (ec)
552 {
553 // doesn't have to include this
554 // interface
555 return;
556 }
557
558 const std::string *value =
559 std::get_if<std::string>(&property);
560 if (value != nullptr)
561 {
562 aResp->res.jsonValue["AssetTag"] =
563 *value;
564 }
565 },
566 connection.first, path,
567 "org.freedesktop.DBus.Properties", "Get",
568 "xyz.openbmc_project.Inventory.Decorator."
569 "AssetTag",
570 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700571 }
572 }
573 }
574 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700575 },
576 "xyz.openbmc_project.ObjectMapper",
577 "/xyz/openbmc_project/object_mapper",
578 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700579 "/xyz/openbmc_project/inventory", int32_t(0),
580 std::array<const char *, 5>{
581 "xyz.openbmc_project.Inventory.Decorator.Asset",
582 "xyz.openbmc_project.Inventory.Item.Cpu",
583 "xyz.openbmc_project.Inventory.Item.Dimm",
584 "xyz.openbmc_project.Inventory.Item.System",
585 "xyz.openbmc_project.Common.UUID",
586 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700587}
588
589/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700590 * @brief Retrieves host state properties over dbus
591 *
592 * @param[in] aResp Shared pointer for completing asynchronous calls.
593 *
594 * @return None.
595 */
596void getHostState(std::shared_ptr<AsyncResp> aResp)
597{
598 BMCWEB_LOG_DEBUG << "Get host information.";
599 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800600 [aResp](const boost::system::error_code ec,
601 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700602 if (ec)
603 {
604 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700605 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700606 return;
607 }
Ed Tanous66173382018-08-15 18:20:59 -0700608
Ed Tanousabf2add2019-01-22 16:40:12 -0800609 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700610 BMCWEB_LOG_DEBUG << "Host state: " << *s;
611 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700612 {
Ed Tanous66173382018-08-15 18:20:59 -0700613 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800614 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700615 {
Ed Tanous66173382018-08-15 18:20:59 -0700616 aResp->res.jsonValue["PowerState"] = "On";
617 aResp->res.jsonValue["Status"]["State"] = "Enabled";
618 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600619 else if (*s == "xyz.openbmc_project.State.Host.HostState."
620 "DiagnosticMode")
621 {
622 aResp->res.jsonValue["PowerState"] = "On";
623 aResp->res.jsonValue["Status"]["State"] = "InTest";
624 }
Ed Tanous66173382018-08-15 18:20:59 -0700625 else
626 {
627 aResp->res.jsonValue["PowerState"] = "Off";
628 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700629 }
630 }
631 },
632 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700633 "org.freedesktop.DBus.Properties", "Get",
634 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700635}
636
637/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530638 * @brief Traslates boot source DBUS property value to redfish.
639 *
640 * @param[in] dbusSource The boot source in DBUS speak.
641 *
642 * @return Returns as a string, the boot source in Redfish terms. If translation
643 * cannot be done, returns an empty string.
644 */
645static std::string dbusToRfBootSource(const std::string &dbusSource)
646{
647 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
648 {
649 return "None";
650 }
651 else if (dbusSource ==
652 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
653 {
654 return "Hdd";
655 }
656 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530657 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530658 {
659 return "Cd";
660 }
661 else if (dbusSource ==
662 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
663 {
664 return "Pxe";
665 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700666 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700667 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700668 {
669 return "Usb";
670 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530671 else
672 {
673 return "";
674 }
675}
676
677/**
678 * @brief Traslates boot mode DBUS property value to redfish.
679 *
680 * @param[in] dbusMode The boot mode in DBUS speak.
681 *
682 * @return Returns as a string, the boot mode in Redfish terms. If translation
683 * cannot be done, returns an empty string.
684 */
685static std::string dbusToRfBootMode(const std::string &dbusMode)
686{
687 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
688 {
689 return "None";
690 }
691 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
692 {
693 return "Diags";
694 }
695 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
696 {
697 return "BiosSetup";
698 }
699 else
700 {
701 return "";
702 }
703}
704
705/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700706 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530707 *
708 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700709 * @param[out] bootSource The DBus source
710 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530711 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700712 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530713 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700714static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
715 const std::string &rfSource,
716 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530717{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700718 // The caller has initialized the bootSource and bootMode to:
719 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
720 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
721 // Only modify the bootSource/bootMode variable needed to achieve the
722 // desired boot action.
723
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530724 if (rfSource == "None")
725 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700726 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530727 }
728 else if (rfSource == "Pxe")
729 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700730 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
731 }
732 else if (rfSource == "Hdd")
733 {
734 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
735 }
736 else if (rfSource == "Diags")
737 {
738 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
739 }
740 else if (rfSource == "Cd")
741 {
742 bootSource =
743 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
744 }
745 else if (rfSource == "BiosSetup")
746 {
747 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530748 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700749 else if (rfSource == "Usb")
750 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700751 bootSource =
752 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700753 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530754 else
755 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700756 BMCWEB_LOG_DEBUG << "Invalid property value for "
757 "BootSourceOverrideTarget: "
758 << bootSource;
759 messages::propertyValueNotInList(aResp->res, rfSource,
760 "BootSourceTargetOverride");
761 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530762 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700763 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530764}
765
766/**
767 * @brief Retrieves boot mode over DBUS and fills out the response
768 *
769 * @param[in] aResp Shared pointer for generating response message.
770 * @param[in] bootDbusObj The dbus object to query for boot properties.
771 *
772 * @return None.
773 */
774static void getBootMode(std::shared_ptr<AsyncResp> aResp,
775 std::string bootDbusObj)
776{
777 crow::connections::systemBus->async_method_call(
778 [aResp](const boost::system::error_code ec,
779 const std::variant<std::string> &bootMode) {
780 if (ec)
781 {
782 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
783 messages::internalError(aResp->res);
784 return;
785 }
786
787 const std::string *bootModeStr =
788 std::get_if<std::string>(&bootMode);
789
790 if (!bootModeStr)
791 {
792 messages::internalError(aResp->res);
793 return;
794 }
795
796 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
797
798 // TODO (Santosh): Do we need to support override mode?
799 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
800 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
801 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700802 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530803
804 if (*bootModeStr !=
805 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
806 {
807 auto rfMode = dbusToRfBootMode(*bootModeStr);
808 if (!rfMode.empty())
809 {
810 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
811 rfMode;
812 }
813 }
814
815 // If the BootSourceOverrideTarget is still "None" at the end,
816 // reset the BootSourceOverrideEnabled to indicate that
817 // overrides are disabled
818 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
819 "None")
820 {
821 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
822 "Disabled";
823 }
824 },
825 "xyz.openbmc_project.Settings", bootDbusObj,
826 "org.freedesktop.DBus.Properties", "Get",
827 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
828}
829
830/**
831 * @brief Retrieves boot source over DBUS
832 *
833 * @param[in] aResp Shared pointer for generating response message.
834 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
835 *
836 * @return None.
837 */
838static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
839{
840 std::string bootDbusObj =
841 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
842 : "/xyz/openbmc_project/control/host0/boot";
843
844 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
845 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
846 (oneTimeEnabled) ? "Once" : "Continuous";
847
848 crow::connections::systemBus->async_method_call(
849 [aResp, bootDbusObj](const boost::system::error_code ec,
850 const std::variant<std::string> &bootSource) {
851 if (ec)
852 {
853 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
854 messages::internalError(aResp->res);
855 return;
856 }
857
858 const std::string *bootSourceStr =
859 std::get_if<std::string>(&bootSource);
860
861 if (!bootSourceStr)
862 {
863 messages::internalError(aResp->res);
864 return;
865 }
866 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
867
868 auto rfSource = dbusToRfBootSource(*bootSourceStr);
869 if (!rfSource.empty())
870 {
871 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
872 rfSource;
873 }
874 },
875 "xyz.openbmc_project.Settings", bootDbusObj,
876 "org.freedesktop.DBus.Properties", "Get",
877 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
878 getBootMode(std::move(aResp), std::move(bootDbusObj));
879}
880
881/**
882 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
883 * get boot source and boot mode.
884 *
885 * @param[in] aResp Shared pointer for generating response message.
886 *
887 * @return None.
888 */
889static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
890{
891 BMCWEB_LOG_DEBUG << "Get boot information.";
892
893 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800894 [aResp](const boost::system::error_code ec,
895 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530896 if (ec)
897 {
898 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700899 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530900 return;
901 }
902
903 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
904
905 if (!oneTimePtr)
906 {
907 messages::internalError(aResp->res);
908 return;
909 }
910 getBootSource(aResp, *oneTimePtr);
911 },
912 "xyz.openbmc_project.Settings",
913 "/xyz/openbmc_project/control/host0/boot/one_time",
914 "org.freedesktop.DBus.Properties", "Get",
915 "xyz.openbmc_project.Object.Enable", "Enabled");
916}
917
918/**
919 * @brief Sets boot properties into DBUS object(s).
920 *
921 * @param[in] aResp Shared pointer for generating response message.
922 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
923 * @param[in] bootSource The boot source to set.
924 * @param[in] bootEnable The source override "enable" to set.
925 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700926 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530927 */
928static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
929 bool oneTimeEnabled,
930 std::optional<std::string> bootSource,
931 std::optional<std::string> bootEnable)
932{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700933 std::string bootSourceStr =
934 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
935 std::string bootModeStr =
936 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530937 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700938 bool useBootSource = true;
939
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530940 // Validate incoming parameters
941 if (bootEnable)
942 {
943 if (*bootEnable == "Once")
944 {
945 oneTimeSetting = true;
946 }
947 else if (*bootEnable == "Continuous")
948 {
949 oneTimeSetting = false;
950 }
951 else if (*bootEnable == "Disabled")
952 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700953 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530954 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700955 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530956 }
957 else
958 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530959 BMCWEB_LOG_DEBUG << "Unsupported value for "
960 "BootSourceOverrideEnabled: "
961 << *bootEnable;
962 messages::propertyValueNotInList(aResp->res, *bootEnable,
963 "BootSourceOverrideEnabled");
964 return;
965 }
966 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530967
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700968 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530969 {
970 // Source target specified
971 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
972 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700973 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
974 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530975 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700976 BMCWEB_LOG_DEBUG
977 << "Invalid property value for BootSourceOverrideTarget: "
978 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530979 messages::propertyValueNotInList(aResp->res, *bootSource,
980 "BootSourceTargetOverride");
981 return;
982 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700983 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530984
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700985 // Act on validated parameters
986 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
987 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
988 const char *bootObj =
989 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
990 : "/xyz/openbmc_project/control/host0/boot";
991
992 crow::connections::systemBus->async_method_call(
993 [aResp](const boost::system::error_code ec) {
994 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530995 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700996 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
997 messages::internalError(aResp->res);
998 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530999 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001000 BMCWEB_LOG_DEBUG << "Boot source update done.";
1001 },
1002 "xyz.openbmc_project.Settings", bootObj,
1003 "org.freedesktop.DBus.Properties", "Set",
1004 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1005 std::variant<std::string>(bootSourceStr));
1006
1007 crow::connections::systemBus->async_method_call(
1008 [aResp](const boost::system::error_code ec) {
1009 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301010 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001011 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1012 messages::internalError(aResp->res);
1013 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301014 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001015 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1016 },
1017 "xyz.openbmc_project.Settings", bootObj,
1018 "org.freedesktop.DBus.Properties", "Set",
1019 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1020 std::variant<std::string>(bootModeStr));
1021
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301022 crow::connections::systemBus->async_method_call(
1023 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1024 if (ec)
1025 {
1026 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1027 messages::internalError(aResp->res);
1028 return;
1029 }
1030 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1031 },
1032 "xyz.openbmc_project.Settings",
1033 "/xyz/openbmc_project/control/host0/boot/one_time",
1034 "org.freedesktop.DBus.Properties", "Set",
1035 "xyz.openbmc_project.Object.Enable", "Enabled",
1036 std::variant<bool>(oneTimeSetting));
1037}
1038
1039/**
1040 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1041 * set boot source/boot mode properties.
1042 *
1043 * @param[in] aResp Shared pointer for generating response message.
1044 * @param[in] bootSource The boot source from incoming RF request.
1045 * @param[in] bootEnable The boot override enable from incoming RF request.
1046 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001047 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301048 */
1049static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1050 std::optional<std::string> bootSource,
1051 std::optional<std::string> bootEnable)
1052{
1053 BMCWEB_LOG_DEBUG << "Set boot information.";
1054
1055 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001056 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301057 bootEnable{std::move(bootEnable)}](
1058 const boost::system::error_code ec,
1059 const sdbusplus::message::variant<bool> &oneTime) {
1060 if (ec)
1061 {
1062 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1063 messages::internalError(aResp->res);
1064 return;
1065 }
1066
1067 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1068
1069 if (!oneTimePtr)
1070 {
1071 messages::internalError(aResp->res);
1072 return;
1073 }
1074
1075 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1076
1077 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1078 std::move(bootEnable));
1079 },
1080 "xyz.openbmc_project.Settings",
1081 "/xyz/openbmc_project/control/host0/boot/one_time",
1082 "org.freedesktop.DBus.Properties", "Get",
1083 "xyz.openbmc_project.Object.Enable", "Enabled");
1084}
1085
AppaRao Pulia6349912019-10-18 17:16:08 +05301086#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1087/**
1088 * @brief Retrieves provisioning status
1089 *
1090 * @param[in] aResp Shared pointer for completing asynchronous calls.
1091 *
1092 * @return None.
1093 */
1094void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1095{
1096 BMCWEB_LOG_DEBUG << "Get OEM information.";
1097 crow::connections::systemBus->async_method_call(
1098 [aResp](const boost::system::error_code ec,
1099 const std::vector<std::pair<std::string, VariantType>>
1100 &propertiesList) {
1101 if (ec)
1102 {
1103 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1104 messages::internalError(aResp->res);
1105 return;
1106 }
1107
1108 const bool *provState = nullptr;
1109 const bool *lockState = nullptr;
1110 for (const std::pair<std::string, VariantType> &property :
1111 propertiesList)
1112 {
1113 if (property.first == "UfmProvisioned")
1114 {
1115 provState = std::get_if<bool>(&property.second);
1116 }
1117 else if (property.first == "UfmLocked")
1118 {
1119 lockState = std::get_if<bool>(&property.second);
1120 }
1121 }
1122
1123 if ((provState == nullptr) || (lockState == nullptr))
1124 {
1125 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1126 messages::internalError(aResp->res);
1127 return;
1128 }
1129
1130 nlohmann::json &oemPFR =
1131 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1132 if (*provState == true)
1133 {
1134 if (*lockState == true)
1135 {
1136 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1137 }
1138 else
1139 {
1140 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1141 }
1142 }
1143 else
1144 {
1145 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1146 }
1147 },
1148 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1149 "org.freedesktop.DBus.Properties", "GetAll",
1150 "xyz.openbmc_project.PFR.Attributes");
1151}
1152#endif
1153
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301154/**
Yong Li51709ff2019-09-30 14:13:04 +08001155 * @brief Translates watchdog timeout action DBUS property value to redfish.
1156 *
1157 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1158 *
1159 * @return Returns as a string, the timeout action in Redfish terms. If
1160 * translation cannot be done, returns an empty string.
1161 */
1162static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1163{
1164 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1165 {
1166 return "None";
1167 }
1168 else if (dbusAction ==
1169 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1170 {
1171 return "ResetSystem";
1172 }
1173 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1174 {
1175 return "PowerDown";
1176 }
1177 else if (dbusAction ==
1178 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1179 {
1180 return "PowerCycle";
1181 }
1182
1183 return "";
1184}
1185
1186/**
Yong Lic45f0082019-10-10 14:19:01 +08001187 *@brief Translates timeout action from Redfish to DBUS property value.
1188 *
1189 *@param[in] rfAction The timeout action in Redfish.
1190 *
1191 *@return Returns as a string, the time_out action as expected by DBUS.
1192 *If translation cannot be done, returns an empty string.
1193 */
1194
1195static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1196{
1197 if (rfAction == "None")
1198 {
1199 return "xyz.openbmc_project.State.Watchdog.Action.None";
1200 }
1201 else if (rfAction == "PowerCycle")
1202 {
1203 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1204 }
1205 else if (rfAction == "PowerDown")
1206 {
1207 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1208 }
1209 else if (rfAction == "ResetSystem")
1210 {
1211 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1212 }
1213
1214 return "";
1215}
1216
1217/**
Yong Li51709ff2019-09-30 14:13:04 +08001218 * @brief Retrieves host watchdog timer properties over DBUS
1219 *
1220 * @param[in] aResp Shared pointer for completing asynchronous calls.
1221 *
1222 * @return None.
1223 */
1224void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1225{
1226 BMCWEB_LOG_DEBUG << "Get host watchodg";
1227 crow::connections::systemBus->async_method_call(
1228 [aResp](const boost::system::error_code ec,
1229 PropertiesType &properties) {
1230 if (ec)
1231 {
1232 // watchdog service is stopped
1233 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1234 return;
1235 }
1236
1237 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1238
1239 nlohmann::json &hostWatchdogTimer =
1240 aResp->res.jsonValue["HostWatchdogTimer"];
1241
1242 // watchdog service is running/enabled
1243 hostWatchdogTimer["Status"]["State"] = "Enabled";
1244
1245 for (const auto &property : properties)
1246 {
1247 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1248 if (property.first == "Enabled")
1249 {
1250 const bool *state = std::get_if<bool>(&property.second);
1251
1252 if (!state)
1253 {
1254 messages::internalError(aResp->res);
1255 continue;
1256 }
1257
1258 hostWatchdogTimer["FunctionEnabled"] = *state;
1259 }
1260 else if (property.first == "ExpireAction")
1261 {
1262 const std::string *s =
1263 std::get_if<std::string>(&property.second);
1264 if (!s)
1265 {
1266 messages::internalError(aResp->res);
1267 continue;
1268 }
1269
1270 std::string action = dbusToRfWatchdogAction(*s);
1271 if (action.empty())
1272 {
1273 messages::internalError(aResp->res);
1274 continue;
1275 }
1276 hostWatchdogTimer["TimeoutAction"] = action;
1277 }
1278 }
1279 },
1280 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1281 "org.freedesktop.DBus.Properties", "GetAll",
1282 "xyz.openbmc_project.State.Watchdog");
1283}
1284
1285/**
Yong Lic45f0082019-10-10 14:19:01 +08001286 * @brief Sets Host WatchDog Timer properties.
1287 *
1288 * @param[in] aResp Shared pointer for generating response message.
1289 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1290 * RF request.
1291 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1292 *
1293 * @return None.
1294 */
1295static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1296 const std::optional<bool> wdtEnable,
1297 const std::optional<std::string> &wdtTimeOutAction)
1298{
1299 BMCWEB_LOG_DEBUG << "Set host watchdog";
1300
1301 if (wdtTimeOutAction)
1302 {
1303 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1304 // check if TimeOut Action is Valid
1305 if (wdtTimeOutActStr.empty())
1306 {
1307 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1308 << *wdtTimeOutAction;
1309 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1310 "TimeoutAction");
1311 return;
1312 }
1313
1314 crow::connections::systemBus->async_method_call(
1315 [aResp](const boost::system::error_code ec) {
1316 if (ec)
1317 {
1318 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1319 messages::internalError(aResp->res);
1320 return;
1321 }
1322 },
1323 "xyz.openbmc_project.Watchdog",
1324 "/xyz/openbmc_project/watchdog/host0",
1325 "org.freedesktop.DBus.Properties", "Set",
1326 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1327 std::variant<std::string>(wdtTimeOutActStr));
1328 }
1329
1330 if (wdtEnable)
1331 {
1332 crow::connections::systemBus->async_method_call(
1333 [aResp](const boost::system::error_code ec) {
1334 if (ec)
1335 {
1336 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1337 messages::internalError(aResp->res);
1338 return;
1339 }
1340 },
1341 "xyz.openbmc_project.Watchdog",
1342 "/xyz/openbmc_project/watchdog/host0",
1343 "org.freedesktop.DBus.Properties", "Set",
1344 "xyz.openbmc_project.State.Watchdog", "Enabled",
1345 std::variant<bool>(*wdtEnable));
1346 }
1347}
1348
1349/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001350 * SystemsCollection derived class for delivering ComputerSystems Collection
1351 * Schema
1352 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001353class SystemsCollection : public Node
1354{
1355 public:
1356 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1357 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001358 entityPrivileges = {
1359 {boost::beast::http::verb::get, {{"Login"}}},
1360 {boost::beast::http::verb::head, {{"Login"}}},
1361 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1362 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1363 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1364 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1365 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001366
Ed Tanous1abe55e2018-09-05 08:30:59 -07001367 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001368 void doGet(crow::Response &res, const crow::Request &req,
1369 const std::vector<std::string> &params) override
1370 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001371 res.jsonValue["@odata.type"] =
1372 "#ComputerSystemCollection.ComputerSystemCollection";
1373 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001374 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001375 res.jsonValue["Members"] = {
1376 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1377 res.jsonValue["Members@odata.count"] = 1;
1378 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001379 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001380};
1381
1382/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001383 * SystemActionsReset class supports handle POST method for Reset action.
1384 * The class retrieves and sends data directly to D-Bus.
1385 */
1386class SystemActionsReset : public Node
1387{
1388 public:
1389 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001390 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001391 {
1392 entityPrivileges = {
1393 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1394 }
1395
1396 private:
1397 /**
1398 * Function handles POST method request.
1399 * Analyzes POST body message before sends Reset request data to D-Bus.
1400 */
1401 void doPost(crow::Response &res, const crow::Request &req,
1402 const std::vector<std::string> &params) override
1403 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001404 auto asyncResp = std::make_shared<AsyncResp>(res);
1405
1406 std::string resetType;
1407 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001408 {
1409 return;
1410 }
1411
Jason M. Billsd22c8392019-06-03 13:59:03 -07001412 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001413 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001414 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001415 if (resetType == "On")
1416 {
1417 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001418 hostCommand = true;
1419 }
1420 else if (resetType == "ForceOff")
1421 {
1422 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1423 hostCommand = false;
1424 }
1425 else if (resetType == "ForceOn")
1426 {
1427 command = "xyz.openbmc_project.State.Host.Transition.On";
1428 hostCommand = true;
1429 }
1430 else if (resetType == "ForceRestart")
1431 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001432 command =
1433 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1434 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001435 }
1436 else if (resetType == "GracefulShutdown")
1437 {
1438 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001439 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001440 }
1441 else if (resetType == "GracefulRestart")
1442 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001443 command =
1444 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001445 hostCommand = true;
1446 }
1447 else if (resetType == "PowerCycle")
1448 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001449 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1450 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001451 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001452 else if (resetType == "Nmi")
1453 {
1454 doNMI(asyncResp);
1455 return;
1456 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001457 else
1458 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001459 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001460 return;
1461 }
1462
Jason M. Billsd22c8392019-06-03 13:59:03 -07001463 if (hostCommand)
1464 {
1465 crow::connections::systemBus->async_method_call(
1466 [asyncResp, resetType](const boost::system::error_code ec) {
1467 if (ec)
1468 {
1469 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1470 if (ec.value() == boost::asio::error::invalid_argument)
1471 {
1472 messages::actionParameterNotSupported(
1473 asyncResp->res, resetType, "Reset");
1474 }
1475 else
1476 {
1477 messages::internalError(asyncResp->res);
1478 }
1479 return;
1480 }
1481 messages::success(asyncResp->res);
1482 },
1483 "xyz.openbmc_project.State.Host",
1484 "/xyz/openbmc_project/state/host0",
1485 "org.freedesktop.DBus.Properties", "Set",
1486 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1487 std::variant<std::string>{command});
1488 }
1489 else
1490 {
1491 crow::connections::systemBus->async_method_call(
1492 [asyncResp, resetType](const boost::system::error_code ec) {
1493 if (ec)
1494 {
1495 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1496 if (ec.value() == boost::asio::error::invalid_argument)
1497 {
1498 messages::actionParameterNotSupported(
1499 asyncResp->res, resetType, "Reset");
1500 }
1501 else
1502 {
1503 messages::internalError(asyncResp->res);
1504 }
1505 return;
1506 }
1507 messages::success(asyncResp->res);
1508 },
1509 "xyz.openbmc_project.State.Chassis",
1510 "/xyz/openbmc_project/state/chassis0",
1511 "org.freedesktop.DBus.Properties", "Set",
1512 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1513 std::variant<std::string>{command});
1514 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001515 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001516 /**
1517 * Function transceives data with dbus directly.
1518 */
1519 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1520 {
1521 constexpr char const *serviceName =
1522 "xyz.openbmc_project.Control.Host.NMI";
1523 constexpr char const *objectPath =
1524 "/xyz/openbmc_project/control/host0/nmi";
1525 constexpr char const *interfaceName =
1526 "xyz.openbmc_project.Control.Host.NMI";
1527 constexpr char const *method = "NMI";
1528
1529 crow::connections::systemBus->async_method_call(
1530 [asyncResp](const boost::system::error_code ec) {
1531 if (ec)
1532 {
1533 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1534 messages::internalError(asyncResp->res);
1535 return;
1536 }
1537 messages::success(asyncResp->res);
1538 },
1539 serviceName, objectPath, interfaceName, method);
1540 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001541};
1542
1543/**
Ed Tanous66173382018-08-15 18:20:59 -07001544 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001545 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001546class Systems : public Node
1547{
1548 public:
1549 /*
1550 * Default Constructor
1551 */
Ed Tanous029573d2019-02-01 10:57:49 -08001552 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001553 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001554 entityPrivileges = {
1555 {boost::beast::http::verb::get, {{"Login"}}},
1556 {boost::beast::http::verb::head, {{"Login"}}},
1557 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1558 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1559 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1560 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001561 }
1562
Ed Tanous1abe55e2018-09-05 08:30:59 -07001563 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001564 /**
1565 * Functions triggers appropriate requests on DBus
1566 */
1567 void doGet(crow::Response &res, const crow::Request &req,
1568 const std::vector<std::string> &params) override
1569 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301570 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001571 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001572 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001573 res.jsonValue["SystemType"] = "Physical";
1574 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001575 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1576 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001577 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001578 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001579 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001580
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001581 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001582 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001583 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001584 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001585 res.jsonValue["Storage"] = {
1586 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001587
Ed Tanouscc340dd2018-08-29 13:43:38 -07001588 // TODO Need to support ForceRestart.
1589 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1590 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001591 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001592 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001593 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001594 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001595
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001596 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001597 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001598
Carol Wangd82a3ac2019-11-21 13:56:38 +08001599 res.jsonValue["Bios"] = {
1600 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1601
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001602 res.jsonValue["Links"]["ManagedBy"] = {
1603 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1604
1605 res.jsonValue["Status"] = {
1606 {"Health", "OK"},
1607 {"State", "Enabled"},
1608 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001609 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001610
James Feiste284a7c2019-11-20 16:20:23 -08001611 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001612 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001613 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001614 "xyz.openbmc_project.Inventory.Item.Drive",
1615 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001616
1617 auto health = std::make_shared<HealthPopulate>(asyncResp);
1618 crow::connections::systemBus->async_method_call(
1619 [health](const boost::system::error_code ec,
1620 std::vector<std::string> &resp) {
1621 if (ec)
1622 {
1623 // no inventory
1624 return;
1625 }
1626
1627 health->inventory = std::move(resp);
1628 },
1629 "xyz.openbmc_project.ObjectMapper",
1630 "/xyz/openbmc_project/object_mapper",
1631 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1632 int32_t(0), inventoryForSystems);
1633
1634 health->populate();
1635
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001636 getMainChassisId(asyncResp, [](const std::string &chassisId,
1637 std::shared_ptr<AsyncResp> aRsp) {
1638 aRsp->res.jsonValue["Links"]["Chassis"] = {
1639 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1640 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301641
1642 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001643 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001644 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301645 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001646 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001647 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301648#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1649 getProvisioningStatus(asyncResp);
1650#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001651 }
1652
Ed Tanous1abe55e2018-09-05 08:30:59 -07001653 void doPatch(crow::Response &res, const crow::Request &req,
1654 const std::vector<std::string> &params) override
1655 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301656 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301657 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001658 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001659 auto asyncResp = std::make_shared<AsyncResp>(res);
1660
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001661 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001662 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001663 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001664 return;
1665 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301666
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001667 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001668
1669 if (wdtTimerProps)
1670 {
1671 std::optional<bool> wdtEnable;
1672 std::optional<std::string> wdtTimeOutAction;
1673
1674 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1675 "FunctionEnabled", wdtEnable,
1676 "TimeoutAction", wdtTimeOutAction))
1677 {
1678 return;
1679 }
1680 setWDTProperties(asyncResp, std::move(wdtEnable),
1681 std::move(wdtTimeOutAction));
1682 }
1683
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301684 if (bootProps)
1685 {
1686 std::optional<std::string> bootSource;
1687 std::optional<std::string> bootEnable;
1688
1689 if (!json_util::readJson(*bootProps, asyncResp->res,
1690 "BootSourceOverrideTarget", bootSource,
1691 "BootSourceOverrideEnabled", bootEnable))
1692 {
1693 return;
1694 }
1695 setBootProperties(asyncResp, std::move(bootSource),
1696 std::move(bootEnable));
1697 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001698
Ed Tanous9712f8a2018-09-21 13:38:49 -07001699 if (indicatorLed)
1700 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301701 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001702 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001703 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001704};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001705} // namespace redfish