blob: cae0fe8c8ddd41786530aea2826e777ac281234d [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 }
535 aResp->res.jsonValue["Name"] = "system";
536 aResp->res.jsonValue["Id"] =
537 aResp->res.jsonValue["SerialNumber"];
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600538 // Grab the bios version
539 fw_util::getActiveFwVersion(
540 aResp, fw_util::biosPurpose,
541 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800542 },
543 connection.first, path,
544 "org.freedesktop.DBus.Properties", "GetAll",
545 "xyz.openbmc_project.Inventory.Decorator."
546 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700547
548 crow::connections::systemBus->async_method_call(
549 [aResp](
550 const boost::system::error_code ec,
551 const std::variant<std::string> &property) {
552 if (ec)
553 {
554 // doesn't have to include this
555 // interface
556 return;
557 }
558
559 const std::string *value =
560 std::get_if<std::string>(&property);
561 if (value != nullptr)
562 {
563 aResp->res.jsonValue["AssetTag"] =
564 *value;
565 }
566 },
567 connection.first, path,
568 "org.freedesktop.DBus.Properties", "Get",
569 "xyz.openbmc_project.Inventory.Decorator."
570 "AssetTag",
571 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700572 }
573 }
574 }
575 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700576 },
577 "xyz.openbmc_project.ObjectMapper",
578 "/xyz/openbmc_project/object_mapper",
579 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700580 "/xyz/openbmc_project/inventory", int32_t(0),
581 std::array<const char *, 5>{
582 "xyz.openbmc_project.Inventory.Decorator.Asset",
583 "xyz.openbmc_project.Inventory.Item.Cpu",
584 "xyz.openbmc_project.Inventory.Item.Dimm",
585 "xyz.openbmc_project.Inventory.Item.System",
586 "xyz.openbmc_project.Common.UUID",
587 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700588}
589
590/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700591 * @brief Retrieves host state properties over dbus
592 *
593 * @param[in] aResp Shared pointer for completing asynchronous calls.
594 *
595 * @return None.
596 */
597void getHostState(std::shared_ptr<AsyncResp> aResp)
598{
599 BMCWEB_LOG_DEBUG << "Get host information.";
600 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800601 [aResp](const boost::system::error_code ec,
602 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700603 if (ec)
604 {
605 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700606 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700607 return;
608 }
Ed Tanous66173382018-08-15 18:20:59 -0700609
Ed Tanousabf2add2019-01-22 16:40:12 -0800610 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700611 BMCWEB_LOG_DEBUG << "Host state: " << *s;
612 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700613 {
Ed Tanous66173382018-08-15 18:20:59 -0700614 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800615 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700616 {
Ed Tanous66173382018-08-15 18:20:59 -0700617 aResp->res.jsonValue["PowerState"] = "On";
618 aResp->res.jsonValue["Status"]["State"] = "Enabled";
619 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600620 else if (*s == "xyz.openbmc_project.State.Host.HostState."
621 "DiagnosticMode")
622 {
623 aResp->res.jsonValue["PowerState"] = "On";
624 aResp->res.jsonValue["Status"]["State"] = "InTest";
625 }
Ed Tanous66173382018-08-15 18:20:59 -0700626 else
627 {
628 aResp->res.jsonValue["PowerState"] = "Off";
629 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700630 }
631 }
632 },
633 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700634 "org.freedesktop.DBus.Properties", "Get",
635 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700636}
637
638/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530639 * @brief Traslates boot source DBUS property value to redfish.
640 *
641 * @param[in] dbusSource The boot source in DBUS speak.
642 *
643 * @return Returns as a string, the boot source in Redfish terms. If translation
644 * cannot be done, returns an empty string.
645 */
646static std::string dbusToRfBootSource(const std::string &dbusSource)
647{
648 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
649 {
650 return "None";
651 }
652 else if (dbusSource ==
653 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
654 {
655 return "Hdd";
656 }
657 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530658 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530659 {
660 return "Cd";
661 }
662 else if (dbusSource ==
663 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
664 {
665 return "Pxe";
666 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700667 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700668 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700669 {
670 return "Usb";
671 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530672 else
673 {
674 return "";
675 }
676}
677
678/**
679 * @brief Traslates boot mode DBUS property value to redfish.
680 *
681 * @param[in] dbusMode The boot mode in DBUS speak.
682 *
683 * @return Returns as a string, the boot mode in Redfish terms. If translation
684 * cannot be done, returns an empty string.
685 */
686static std::string dbusToRfBootMode(const std::string &dbusMode)
687{
688 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
689 {
690 return "None";
691 }
692 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
693 {
694 return "Diags";
695 }
696 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
697 {
698 return "BiosSetup";
699 }
700 else
701 {
702 return "";
703 }
704}
705
706/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700707 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530708 *
709 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700710 * @param[out] bootSource The DBus source
711 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700713 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530714 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700715static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
716 const std::string &rfSource,
717 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530718{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700719 // The caller has initialized the bootSource and bootMode to:
720 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
721 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
722 // Only modify the bootSource/bootMode variable needed to achieve the
723 // desired boot action.
724
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530725 if (rfSource == "None")
726 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700727 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530728 }
729 else if (rfSource == "Pxe")
730 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700731 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
732 }
733 else if (rfSource == "Hdd")
734 {
735 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
736 }
737 else if (rfSource == "Diags")
738 {
739 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
740 }
741 else if (rfSource == "Cd")
742 {
743 bootSource =
744 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
745 }
746 else if (rfSource == "BiosSetup")
747 {
748 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530749 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700750 else if (rfSource == "Usb")
751 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700752 bootSource =
753 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700754 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530755 else
756 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700757 BMCWEB_LOG_DEBUG << "Invalid property value for "
758 "BootSourceOverrideTarget: "
759 << bootSource;
760 messages::propertyValueNotInList(aResp->res, rfSource,
761 "BootSourceTargetOverride");
762 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530763 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700764 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530765}
766
767/**
768 * @brief Retrieves boot mode over DBUS and fills out the response
769 *
770 * @param[in] aResp Shared pointer for generating response message.
771 * @param[in] bootDbusObj The dbus object to query for boot properties.
772 *
773 * @return None.
774 */
775static void getBootMode(std::shared_ptr<AsyncResp> aResp,
776 std::string bootDbusObj)
777{
778 crow::connections::systemBus->async_method_call(
779 [aResp](const boost::system::error_code ec,
780 const std::variant<std::string> &bootMode) {
781 if (ec)
782 {
783 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
784 messages::internalError(aResp->res);
785 return;
786 }
787
788 const std::string *bootModeStr =
789 std::get_if<std::string>(&bootMode);
790
791 if (!bootModeStr)
792 {
793 messages::internalError(aResp->res);
794 return;
795 }
796
797 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
798
799 // TODO (Santosh): Do we need to support override mode?
800 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
801 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
802 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700803 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530804
805 if (*bootModeStr !=
806 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
807 {
808 auto rfMode = dbusToRfBootMode(*bootModeStr);
809 if (!rfMode.empty())
810 {
811 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
812 rfMode;
813 }
814 }
815
816 // If the BootSourceOverrideTarget is still "None" at the end,
817 // reset the BootSourceOverrideEnabled to indicate that
818 // overrides are disabled
819 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
820 "None")
821 {
822 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
823 "Disabled";
824 }
825 },
826 "xyz.openbmc_project.Settings", bootDbusObj,
827 "org.freedesktop.DBus.Properties", "Get",
828 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
829}
830
831/**
832 * @brief Retrieves boot source over DBUS
833 *
834 * @param[in] aResp Shared pointer for generating response message.
835 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
836 *
837 * @return None.
838 */
839static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
840{
841 std::string bootDbusObj =
842 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
843 : "/xyz/openbmc_project/control/host0/boot";
844
845 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
846 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
847 (oneTimeEnabled) ? "Once" : "Continuous";
848
849 crow::connections::systemBus->async_method_call(
850 [aResp, bootDbusObj](const boost::system::error_code ec,
851 const std::variant<std::string> &bootSource) {
852 if (ec)
853 {
854 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
855 messages::internalError(aResp->res);
856 return;
857 }
858
859 const std::string *bootSourceStr =
860 std::get_if<std::string>(&bootSource);
861
862 if (!bootSourceStr)
863 {
864 messages::internalError(aResp->res);
865 return;
866 }
867 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
868
869 auto rfSource = dbusToRfBootSource(*bootSourceStr);
870 if (!rfSource.empty())
871 {
872 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
873 rfSource;
874 }
875 },
876 "xyz.openbmc_project.Settings", bootDbusObj,
877 "org.freedesktop.DBus.Properties", "Get",
878 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
879 getBootMode(std::move(aResp), std::move(bootDbusObj));
880}
881
882/**
883 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
884 * get boot source and boot mode.
885 *
886 * @param[in] aResp Shared pointer for generating response message.
887 *
888 * @return None.
889 */
890static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
891{
892 BMCWEB_LOG_DEBUG << "Get boot information.";
893
894 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800895 [aResp](const boost::system::error_code ec,
896 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530897 if (ec)
898 {
899 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700900 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530901 return;
902 }
903
904 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
905
906 if (!oneTimePtr)
907 {
908 messages::internalError(aResp->res);
909 return;
910 }
911 getBootSource(aResp, *oneTimePtr);
912 },
913 "xyz.openbmc_project.Settings",
914 "/xyz/openbmc_project/control/host0/boot/one_time",
915 "org.freedesktop.DBus.Properties", "Get",
916 "xyz.openbmc_project.Object.Enable", "Enabled");
917}
918
919/**
920 * @brief Sets boot properties into DBUS object(s).
921 *
922 * @param[in] aResp Shared pointer for generating response message.
923 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
924 * @param[in] bootSource The boot source to set.
925 * @param[in] bootEnable The source override "enable" to set.
926 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700927 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530928 */
929static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
930 bool oneTimeEnabled,
931 std::optional<std::string> bootSource,
932 std::optional<std::string> bootEnable)
933{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700934 std::string bootSourceStr =
935 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
936 std::string bootModeStr =
937 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530938 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700939 bool useBootSource = true;
940
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530941 // Validate incoming parameters
942 if (bootEnable)
943 {
944 if (*bootEnable == "Once")
945 {
946 oneTimeSetting = true;
947 }
948 else if (*bootEnable == "Continuous")
949 {
950 oneTimeSetting = false;
951 }
952 else if (*bootEnable == "Disabled")
953 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700954 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530955 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700956 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530957 }
958 else
959 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530960 BMCWEB_LOG_DEBUG << "Unsupported value for "
961 "BootSourceOverrideEnabled: "
962 << *bootEnable;
963 messages::propertyValueNotInList(aResp->res, *bootEnable,
964 "BootSourceOverrideEnabled");
965 return;
966 }
967 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530968
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700969 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530970 {
971 // Source target specified
972 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
973 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700974 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
975 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530976 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700977 BMCWEB_LOG_DEBUG
978 << "Invalid property value for BootSourceOverrideTarget: "
979 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530980 messages::propertyValueNotInList(aResp->res, *bootSource,
981 "BootSourceTargetOverride");
982 return;
983 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700984 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530985
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700986 // Act on validated parameters
987 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
988 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
989 const char *bootObj =
990 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
991 : "/xyz/openbmc_project/control/host0/boot";
992
993 crow::connections::systemBus->async_method_call(
994 [aResp](const boost::system::error_code ec) {
995 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530996 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700997 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
998 messages::internalError(aResp->res);
999 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301000 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001001 BMCWEB_LOG_DEBUG << "Boot source update done.";
1002 },
1003 "xyz.openbmc_project.Settings", bootObj,
1004 "org.freedesktop.DBus.Properties", "Set",
1005 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1006 std::variant<std::string>(bootSourceStr));
1007
1008 crow::connections::systemBus->async_method_call(
1009 [aResp](const boost::system::error_code ec) {
1010 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301011 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001012 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1013 messages::internalError(aResp->res);
1014 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301015 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001016 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1017 },
1018 "xyz.openbmc_project.Settings", bootObj,
1019 "org.freedesktop.DBus.Properties", "Set",
1020 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1021 std::variant<std::string>(bootModeStr));
1022
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301023 crow::connections::systemBus->async_method_call(
1024 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1025 if (ec)
1026 {
1027 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1028 messages::internalError(aResp->res);
1029 return;
1030 }
1031 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1032 },
1033 "xyz.openbmc_project.Settings",
1034 "/xyz/openbmc_project/control/host0/boot/one_time",
1035 "org.freedesktop.DBus.Properties", "Set",
1036 "xyz.openbmc_project.Object.Enable", "Enabled",
1037 std::variant<bool>(oneTimeSetting));
1038}
1039
1040/**
1041 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1042 * set boot source/boot mode properties.
1043 *
1044 * @param[in] aResp Shared pointer for generating response message.
1045 * @param[in] bootSource The boot source from incoming RF request.
1046 * @param[in] bootEnable The boot override enable from incoming RF request.
1047 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001048 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301049 */
1050static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1051 std::optional<std::string> bootSource,
1052 std::optional<std::string> bootEnable)
1053{
1054 BMCWEB_LOG_DEBUG << "Set boot information.";
1055
1056 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001057 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301058 bootEnable{std::move(bootEnable)}](
1059 const boost::system::error_code ec,
1060 const sdbusplus::message::variant<bool> &oneTime) {
1061 if (ec)
1062 {
1063 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1064 messages::internalError(aResp->res);
1065 return;
1066 }
1067
1068 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1069
1070 if (!oneTimePtr)
1071 {
1072 messages::internalError(aResp->res);
1073 return;
1074 }
1075
1076 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1077
1078 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1079 std::move(bootEnable));
1080 },
1081 "xyz.openbmc_project.Settings",
1082 "/xyz/openbmc_project/control/host0/boot/one_time",
1083 "org.freedesktop.DBus.Properties", "Get",
1084 "xyz.openbmc_project.Object.Enable", "Enabled");
1085}
1086
AppaRao Pulia6349912019-10-18 17:16:08 +05301087#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1088/**
1089 * @brief Retrieves provisioning status
1090 *
1091 * @param[in] aResp Shared pointer for completing asynchronous calls.
1092 *
1093 * @return None.
1094 */
1095void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1096{
1097 BMCWEB_LOG_DEBUG << "Get OEM information.";
1098 crow::connections::systemBus->async_method_call(
1099 [aResp](const boost::system::error_code ec,
1100 const std::vector<std::pair<std::string, VariantType>>
1101 &propertiesList) {
1102 if (ec)
1103 {
1104 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1105 messages::internalError(aResp->res);
1106 return;
1107 }
1108
1109 const bool *provState = nullptr;
1110 const bool *lockState = nullptr;
1111 for (const std::pair<std::string, VariantType> &property :
1112 propertiesList)
1113 {
1114 if (property.first == "UfmProvisioned")
1115 {
1116 provState = std::get_if<bool>(&property.second);
1117 }
1118 else if (property.first == "UfmLocked")
1119 {
1120 lockState = std::get_if<bool>(&property.second);
1121 }
1122 }
1123
1124 if ((provState == nullptr) || (lockState == nullptr))
1125 {
1126 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1127 messages::internalError(aResp->res);
1128 return;
1129 }
1130
1131 nlohmann::json &oemPFR =
1132 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1133 if (*provState == true)
1134 {
1135 if (*lockState == true)
1136 {
1137 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1138 }
1139 else
1140 {
1141 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1142 }
1143 }
1144 else
1145 {
1146 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1147 }
1148 },
1149 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1150 "org.freedesktop.DBus.Properties", "GetAll",
1151 "xyz.openbmc_project.PFR.Attributes");
1152}
1153#endif
1154
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301155/**
Yong Li51709ff2019-09-30 14:13:04 +08001156 * @brief Translates watchdog timeout action DBUS property value to redfish.
1157 *
1158 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1159 *
1160 * @return Returns as a string, the timeout action in Redfish terms. If
1161 * translation cannot be done, returns an empty string.
1162 */
1163static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1164{
1165 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1166 {
1167 return "None";
1168 }
1169 else if (dbusAction ==
1170 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1171 {
1172 return "ResetSystem";
1173 }
1174 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1175 {
1176 return "PowerDown";
1177 }
1178 else if (dbusAction ==
1179 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1180 {
1181 return "PowerCycle";
1182 }
1183
1184 return "";
1185}
1186
1187/**
Yong Lic45f0082019-10-10 14:19:01 +08001188 *@brief Translates timeout action from Redfish to DBUS property value.
1189 *
1190 *@param[in] rfAction The timeout action in Redfish.
1191 *
1192 *@return Returns as a string, the time_out action as expected by DBUS.
1193 *If translation cannot be done, returns an empty string.
1194 */
1195
1196static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1197{
1198 if (rfAction == "None")
1199 {
1200 return "xyz.openbmc_project.State.Watchdog.Action.None";
1201 }
1202 else if (rfAction == "PowerCycle")
1203 {
1204 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1205 }
1206 else if (rfAction == "PowerDown")
1207 {
1208 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1209 }
1210 else if (rfAction == "ResetSystem")
1211 {
1212 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1213 }
1214
1215 return "";
1216}
1217
1218/**
Yong Li51709ff2019-09-30 14:13:04 +08001219 * @brief Retrieves host watchdog timer properties over DBUS
1220 *
1221 * @param[in] aResp Shared pointer for completing asynchronous calls.
1222 *
1223 * @return None.
1224 */
1225void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1226{
1227 BMCWEB_LOG_DEBUG << "Get host watchodg";
1228 crow::connections::systemBus->async_method_call(
1229 [aResp](const boost::system::error_code ec,
1230 PropertiesType &properties) {
1231 if (ec)
1232 {
1233 // watchdog service is stopped
1234 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1235 return;
1236 }
1237
1238 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1239
1240 nlohmann::json &hostWatchdogTimer =
1241 aResp->res.jsonValue["HostWatchdogTimer"];
1242
1243 // watchdog service is running/enabled
1244 hostWatchdogTimer["Status"]["State"] = "Enabled";
1245
1246 for (const auto &property : properties)
1247 {
1248 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1249 if (property.first == "Enabled")
1250 {
1251 const bool *state = std::get_if<bool>(&property.second);
1252
1253 if (!state)
1254 {
1255 messages::internalError(aResp->res);
1256 continue;
1257 }
1258
1259 hostWatchdogTimer["FunctionEnabled"] = *state;
1260 }
1261 else if (property.first == "ExpireAction")
1262 {
1263 const std::string *s =
1264 std::get_if<std::string>(&property.second);
1265 if (!s)
1266 {
1267 messages::internalError(aResp->res);
1268 continue;
1269 }
1270
1271 std::string action = dbusToRfWatchdogAction(*s);
1272 if (action.empty())
1273 {
1274 messages::internalError(aResp->res);
1275 continue;
1276 }
1277 hostWatchdogTimer["TimeoutAction"] = action;
1278 }
1279 }
1280 },
1281 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1282 "org.freedesktop.DBus.Properties", "GetAll",
1283 "xyz.openbmc_project.State.Watchdog");
1284}
1285
1286/**
Yong Lic45f0082019-10-10 14:19:01 +08001287 * @brief Sets Host WatchDog Timer properties.
1288 *
1289 * @param[in] aResp Shared pointer for generating response message.
1290 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1291 * RF request.
1292 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1293 *
1294 * @return None.
1295 */
1296static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1297 const std::optional<bool> wdtEnable,
1298 const std::optional<std::string> &wdtTimeOutAction)
1299{
1300 BMCWEB_LOG_DEBUG << "Set host watchdog";
1301
1302 if (wdtTimeOutAction)
1303 {
1304 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1305 // check if TimeOut Action is Valid
1306 if (wdtTimeOutActStr.empty())
1307 {
1308 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1309 << *wdtTimeOutAction;
1310 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1311 "TimeoutAction");
1312 return;
1313 }
1314
1315 crow::connections::systemBus->async_method_call(
1316 [aResp](const boost::system::error_code ec) {
1317 if (ec)
1318 {
1319 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1320 messages::internalError(aResp->res);
1321 return;
1322 }
1323 },
1324 "xyz.openbmc_project.Watchdog",
1325 "/xyz/openbmc_project/watchdog/host0",
1326 "org.freedesktop.DBus.Properties", "Set",
1327 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1328 std::variant<std::string>(wdtTimeOutActStr));
1329 }
1330
1331 if (wdtEnable)
1332 {
1333 crow::connections::systemBus->async_method_call(
1334 [aResp](const boost::system::error_code ec) {
1335 if (ec)
1336 {
1337 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1338 messages::internalError(aResp->res);
1339 return;
1340 }
1341 },
1342 "xyz.openbmc_project.Watchdog",
1343 "/xyz/openbmc_project/watchdog/host0",
1344 "org.freedesktop.DBus.Properties", "Set",
1345 "xyz.openbmc_project.State.Watchdog", "Enabled",
1346 std::variant<bool>(*wdtEnable));
1347 }
1348}
1349
1350/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001351 * SystemsCollection derived class for delivering ComputerSystems Collection
1352 * Schema
1353 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001354class SystemsCollection : public Node
1355{
1356 public:
1357 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1358 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001359 entityPrivileges = {
1360 {boost::beast::http::verb::get, {{"Login"}}},
1361 {boost::beast::http::verb::head, {{"Login"}}},
1362 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1363 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1364 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1365 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1366 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001367
Ed Tanous1abe55e2018-09-05 08:30:59 -07001368 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001369 void doGet(crow::Response &res, const crow::Request &req,
1370 const std::vector<std::string> &params) override
1371 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001372 res.jsonValue["@odata.type"] =
1373 "#ComputerSystemCollection.ComputerSystemCollection";
1374 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1375 res.jsonValue["@odata.context"] =
1376 "/redfish/v1/"
1377 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1378 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001379 res.jsonValue["Members"] = {
1380 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1381 res.jsonValue["Members@odata.count"] = 1;
1382 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001383 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001384};
1385
1386/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001387 * SystemActionsReset class supports handle POST method for Reset action.
1388 * The class retrieves and sends data directly to D-Bus.
1389 */
1390class SystemActionsReset : public Node
1391{
1392 public:
1393 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001394 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001395 {
1396 entityPrivileges = {
1397 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1398 }
1399
1400 private:
1401 /**
1402 * Function handles POST method request.
1403 * Analyzes POST body message before sends Reset request data to D-Bus.
1404 */
1405 void doPost(crow::Response &res, const crow::Request &req,
1406 const std::vector<std::string> &params) override
1407 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001408 auto asyncResp = std::make_shared<AsyncResp>(res);
1409
1410 std::string resetType;
1411 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001412 {
1413 return;
1414 }
1415
Jason M. Billsd22c8392019-06-03 13:59:03 -07001416 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001417 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001418 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001419 if (resetType == "On")
1420 {
1421 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001422 hostCommand = true;
1423 }
1424 else if (resetType == "ForceOff")
1425 {
1426 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1427 hostCommand = false;
1428 }
1429 else if (resetType == "ForceOn")
1430 {
1431 command = "xyz.openbmc_project.State.Host.Transition.On";
1432 hostCommand = true;
1433 }
1434 else if (resetType == "ForceRestart")
1435 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001436 command =
1437 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1438 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001439 }
1440 else if (resetType == "GracefulShutdown")
1441 {
1442 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001443 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001444 }
1445 else if (resetType == "GracefulRestart")
1446 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001447 command =
1448 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001449 hostCommand = true;
1450 }
1451 else if (resetType == "PowerCycle")
1452 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001453 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1454 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001455 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001456 else if (resetType == "Nmi")
1457 {
1458 doNMI(asyncResp);
1459 return;
1460 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001461 else
1462 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001463 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001464 return;
1465 }
1466
Jason M. Billsd22c8392019-06-03 13:59:03 -07001467 if (hostCommand)
1468 {
1469 crow::connections::systemBus->async_method_call(
1470 [asyncResp, resetType](const boost::system::error_code ec) {
1471 if (ec)
1472 {
1473 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1474 if (ec.value() == boost::asio::error::invalid_argument)
1475 {
1476 messages::actionParameterNotSupported(
1477 asyncResp->res, resetType, "Reset");
1478 }
1479 else
1480 {
1481 messages::internalError(asyncResp->res);
1482 }
1483 return;
1484 }
1485 messages::success(asyncResp->res);
1486 },
1487 "xyz.openbmc_project.State.Host",
1488 "/xyz/openbmc_project/state/host0",
1489 "org.freedesktop.DBus.Properties", "Set",
1490 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1491 std::variant<std::string>{command});
1492 }
1493 else
1494 {
1495 crow::connections::systemBus->async_method_call(
1496 [asyncResp, resetType](const boost::system::error_code ec) {
1497 if (ec)
1498 {
1499 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1500 if (ec.value() == boost::asio::error::invalid_argument)
1501 {
1502 messages::actionParameterNotSupported(
1503 asyncResp->res, resetType, "Reset");
1504 }
1505 else
1506 {
1507 messages::internalError(asyncResp->res);
1508 }
1509 return;
1510 }
1511 messages::success(asyncResp->res);
1512 },
1513 "xyz.openbmc_project.State.Chassis",
1514 "/xyz/openbmc_project/state/chassis0",
1515 "org.freedesktop.DBus.Properties", "Set",
1516 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1517 std::variant<std::string>{command});
1518 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001519 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001520 /**
1521 * Function transceives data with dbus directly.
1522 */
1523 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1524 {
1525 constexpr char const *serviceName =
1526 "xyz.openbmc_project.Control.Host.NMI";
1527 constexpr char const *objectPath =
1528 "/xyz/openbmc_project/control/host0/nmi";
1529 constexpr char const *interfaceName =
1530 "xyz.openbmc_project.Control.Host.NMI";
1531 constexpr char const *method = "NMI";
1532
1533 crow::connections::systemBus->async_method_call(
1534 [asyncResp](const boost::system::error_code ec) {
1535 if (ec)
1536 {
1537 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1538 messages::internalError(asyncResp->res);
1539 return;
1540 }
1541 messages::success(asyncResp->res);
1542 },
1543 serviceName, objectPath, interfaceName, method);
1544 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001545};
1546
1547/**
Ed Tanous66173382018-08-15 18:20:59 -07001548 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001549 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001550class Systems : public Node
1551{
1552 public:
1553 /*
1554 * Default Constructor
1555 */
Ed Tanous029573d2019-02-01 10:57:49 -08001556 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001557 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001558 entityPrivileges = {
1559 {boost::beast::http::verb::get, {{"Login"}}},
1560 {boost::beast::http::verb::head, {{"Login"}}},
1561 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1562 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1563 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1564 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001565 }
1566
Ed Tanous1abe55e2018-09-05 08:30:59 -07001567 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001568 /**
1569 * Functions triggers appropriate requests on DBus
1570 */
1571 void doGet(crow::Response &res, const crow::Request &req,
1572 const std::vector<std::string> &params) override
1573 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301574 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001575 res.jsonValue["@odata.context"] =
1576 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001577 res.jsonValue["Name"] = "Computer System";
1578 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001579 res.jsonValue["SystemType"] = "Physical";
1580 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001581 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1582 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001583 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001584 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001585 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001586
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001587 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001588 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001589 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001590 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001591 res.jsonValue["Storage"] = {
1592 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001593
Ed Tanouscc340dd2018-08-29 13:43:38 -07001594 // TODO Need to support ForceRestart.
1595 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1596 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001597 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001598 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001599 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001600 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001601
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001602 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001603 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001604
Carol Wangd82a3ac2019-11-21 13:56:38 +08001605 res.jsonValue["Bios"] = {
1606 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1607
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001608 res.jsonValue["Links"]["ManagedBy"] = {
1609 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1610
1611 res.jsonValue["Status"] = {
1612 {"Health", "OK"},
1613 {"State", "Enabled"},
1614 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001615 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001616
James Feiste284a7c2019-11-20 16:20:23 -08001617 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001618 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001619 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001620 "xyz.openbmc_project.Inventory.Item.Drive",
1621 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001622
1623 auto health = std::make_shared<HealthPopulate>(asyncResp);
1624 crow::connections::systemBus->async_method_call(
1625 [health](const boost::system::error_code ec,
1626 std::vector<std::string> &resp) {
1627 if (ec)
1628 {
1629 // no inventory
1630 return;
1631 }
1632
1633 health->inventory = std::move(resp);
1634 },
1635 "xyz.openbmc_project.ObjectMapper",
1636 "/xyz/openbmc_project/object_mapper",
1637 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1638 int32_t(0), inventoryForSystems);
1639
1640 health->populate();
1641
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001642 getMainChassisId(asyncResp, [](const std::string &chassisId,
1643 std::shared_ptr<AsyncResp> aRsp) {
1644 aRsp->res.jsonValue["Links"]["Chassis"] = {
1645 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1646 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301647
1648 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001649 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001650 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301651 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001652 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001653 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301654#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1655 getProvisioningStatus(asyncResp);
1656#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001657 }
1658
Ed Tanous1abe55e2018-09-05 08:30:59 -07001659 void doPatch(crow::Response &res, const crow::Request &req,
1660 const std::vector<std::string> &params) override
1661 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301662 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301663 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001664 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001665 auto asyncResp = std::make_shared<AsyncResp>(res);
1666
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001667 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001668 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001669 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001670 return;
1671 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301672
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001673 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001674
1675 if (wdtTimerProps)
1676 {
1677 std::optional<bool> wdtEnable;
1678 std::optional<std::string> wdtTimeOutAction;
1679
1680 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1681 "FunctionEnabled", wdtEnable,
1682 "TimeoutAction", wdtTimeOutAction))
1683 {
1684 return;
1685 }
1686 setWDTProperties(asyncResp, std::move(wdtEnable),
1687 std::move(wdtTimeOutAction));
1688 }
1689
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301690 if (bootProps)
1691 {
1692 std::optional<std::string> bootSource;
1693 std::optional<std::string> bootEnable;
1694
1695 if (!json_util::readJson(*bootProps, asyncResp->res,
1696 "BootSourceOverrideTarget", bootSource,
1697 "BootSourceOverrideEnabled", bootEnable))
1698 {
1699 return;
1700 }
1701 setBootProperties(asyncResp, std::move(bootSource),
1702 std::move(bootEnable));
1703 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001704
Ed Tanous9712f8a2018-09-21 13:38:49 -07001705 if (indicatorLed)
1706 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301707 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001708 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001709 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001710};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001711} // namespace redfish