blob: 9280d8f356c91952feb6f54e0cb5c0ff758f1e97 [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 }
620 else
621 {
622 aResp->res.jsonValue["PowerState"] = "Off";
623 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700624 }
625 }
626 },
627 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700628 "org.freedesktop.DBus.Properties", "Get",
629 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700630}
631
632/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530633 * @brief Traslates boot source DBUS property value to redfish.
634 *
635 * @param[in] dbusSource The boot source in DBUS speak.
636 *
637 * @return Returns as a string, the boot source in Redfish terms. If translation
638 * cannot be done, returns an empty string.
639 */
640static std::string dbusToRfBootSource(const std::string &dbusSource)
641{
642 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
643 {
644 return "None";
645 }
646 else if (dbusSource ==
647 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
648 {
649 return "Hdd";
650 }
651 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530652 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530653 {
654 return "Cd";
655 }
656 else if (dbusSource ==
657 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
658 {
659 return "Pxe";
660 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700661 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700662 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700663 {
664 return "Usb";
665 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530666 else
667 {
668 return "";
669 }
670}
671
672/**
673 * @brief Traslates boot mode DBUS property value to redfish.
674 *
675 * @param[in] dbusMode The boot mode in DBUS speak.
676 *
677 * @return Returns as a string, the boot mode in Redfish terms. If translation
678 * cannot be done, returns an empty string.
679 */
680static std::string dbusToRfBootMode(const std::string &dbusMode)
681{
682 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
683 {
684 return "None";
685 }
686 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
687 {
688 return "Diags";
689 }
690 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
691 {
692 return "BiosSetup";
693 }
694 else
695 {
696 return "";
697 }
698}
699
700/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700701 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530702 *
703 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700704 * @param[out] bootSource The DBus source
705 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530706 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700707 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530708 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700709static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
710 const std::string &rfSource,
711 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700713 // The caller has initialized the bootSource and bootMode to:
714 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
715 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
716 // Only modify the bootSource/bootMode variable needed to achieve the
717 // desired boot action.
718
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530719 if (rfSource == "None")
720 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700721 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530722 }
723 else if (rfSource == "Pxe")
724 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700725 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
726 }
727 else if (rfSource == "Hdd")
728 {
729 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
730 }
731 else if (rfSource == "Diags")
732 {
733 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
734 }
735 else if (rfSource == "Cd")
736 {
737 bootSource =
738 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
739 }
740 else if (rfSource == "BiosSetup")
741 {
742 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530743 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700744 else if (rfSource == "Usb")
745 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700746 bootSource =
747 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700748 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530749 else
750 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700751 BMCWEB_LOG_DEBUG << "Invalid property value for "
752 "BootSourceOverrideTarget: "
753 << bootSource;
754 messages::propertyValueNotInList(aResp->res, rfSource,
755 "BootSourceTargetOverride");
756 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530757 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700758 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530759}
760
761/**
762 * @brief Retrieves boot mode over DBUS and fills out the response
763 *
764 * @param[in] aResp Shared pointer for generating response message.
765 * @param[in] bootDbusObj The dbus object to query for boot properties.
766 *
767 * @return None.
768 */
769static void getBootMode(std::shared_ptr<AsyncResp> aResp,
770 std::string bootDbusObj)
771{
772 crow::connections::systemBus->async_method_call(
773 [aResp](const boost::system::error_code ec,
774 const std::variant<std::string> &bootMode) {
775 if (ec)
776 {
777 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
778 messages::internalError(aResp->res);
779 return;
780 }
781
782 const std::string *bootModeStr =
783 std::get_if<std::string>(&bootMode);
784
785 if (!bootModeStr)
786 {
787 messages::internalError(aResp->res);
788 return;
789 }
790
791 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
792
793 // TODO (Santosh): Do we need to support override mode?
794 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
795 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
796 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700797 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530798
799 if (*bootModeStr !=
800 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
801 {
802 auto rfMode = dbusToRfBootMode(*bootModeStr);
803 if (!rfMode.empty())
804 {
805 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
806 rfMode;
807 }
808 }
809
810 // If the BootSourceOverrideTarget is still "None" at the end,
811 // reset the BootSourceOverrideEnabled to indicate that
812 // overrides are disabled
813 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
814 "None")
815 {
816 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
817 "Disabled";
818 }
819 },
820 "xyz.openbmc_project.Settings", bootDbusObj,
821 "org.freedesktop.DBus.Properties", "Get",
822 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
823}
824
825/**
826 * @brief Retrieves boot source over DBUS
827 *
828 * @param[in] aResp Shared pointer for generating response message.
829 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
830 *
831 * @return None.
832 */
833static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
834{
835 std::string bootDbusObj =
836 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
837 : "/xyz/openbmc_project/control/host0/boot";
838
839 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
840 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
841 (oneTimeEnabled) ? "Once" : "Continuous";
842
843 crow::connections::systemBus->async_method_call(
844 [aResp, bootDbusObj](const boost::system::error_code ec,
845 const std::variant<std::string> &bootSource) {
846 if (ec)
847 {
848 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
849 messages::internalError(aResp->res);
850 return;
851 }
852
853 const std::string *bootSourceStr =
854 std::get_if<std::string>(&bootSource);
855
856 if (!bootSourceStr)
857 {
858 messages::internalError(aResp->res);
859 return;
860 }
861 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
862
863 auto rfSource = dbusToRfBootSource(*bootSourceStr);
864 if (!rfSource.empty())
865 {
866 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
867 rfSource;
868 }
869 },
870 "xyz.openbmc_project.Settings", bootDbusObj,
871 "org.freedesktop.DBus.Properties", "Get",
872 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
873 getBootMode(std::move(aResp), std::move(bootDbusObj));
874}
875
876/**
877 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
878 * get boot source and boot mode.
879 *
880 * @param[in] aResp Shared pointer for generating response message.
881 *
882 * @return None.
883 */
884static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
885{
886 BMCWEB_LOG_DEBUG << "Get boot information.";
887
888 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800889 [aResp](const boost::system::error_code ec,
890 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530891 if (ec)
892 {
893 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700894 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530895 return;
896 }
897
898 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
899
900 if (!oneTimePtr)
901 {
902 messages::internalError(aResp->res);
903 return;
904 }
905 getBootSource(aResp, *oneTimePtr);
906 },
907 "xyz.openbmc_project.Settings",
908 "/xyz/openbmc_project/control/host0/boot/one_time",
909 "org.freedesktop.DBus.Properties", "Get",
910 "xyz.openbmc_project.Object.Enable", "Enabled");
911}
912
913/**
914 * @brief Sets boot properties into DBUS object(s).
915 *
916 * @param[in] aResp Shared pointer for generating response message.
917 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
918 * @param[in] bootSource The boot source to set.
919 * @param[in] bootEnable The source override "enable" to set.
920 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700921 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530922 */
923static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
924 bool oneTimeEnabled,
925 std::optional<std::string> bootSource,
926 std::optional<std::string> bootEnable)
927{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700928 std::string bootSourceStr =
929 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
930 std::string bootModeStr =
931 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530932 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700933 bool useBootSource = true;
934
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530935 // Validate incoming parameters
936 if (bootEnable)
937 {
938 if (*bootEnable == "Once")
939 {
940 oneTimeSetting = true;
941 }
942 else if (*bootEnable == "Continuous")
943 {
944 oneTimeSetting = false;
945 }
946 else if (*bootEnable == "Disabled")
947 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700948 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530949 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700950 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530951 }
952 else
953 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530954 BMCWEB_LOG_DEBUG << "Unsupported value for "
955 "BootSourceOverrideEnabled: "
956 << *bootEnable;
957 messages::propertyValueNotInList(aResp->res, *bootEnable,
958 "BootSourceOverrideEnabled");
959 return;
960 }
961 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530962
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700963 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530964 {
965 // Source target specified
966 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
967 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700968 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
969 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530970 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700971 BMCWEB_LOG_DEBUG
972 << "Invalid property value for BootSourceOverrideTarget: "
973 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974 messages::propertyValueNotInList(aResp->res, *bootSource,
975 "BootSourceTargetOverride");
976 return;
977 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700978 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530979
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700980 // Act on validated parameters
981 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
982 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
983 const char *bootObj =
984 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
985 : "/xyz/openbmc_project/control/host0/boot";
986
987 crow::connections::systemBus->async_method_call(
988 [aResp](const boost::system::error_code ec) {
989 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530990 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700991 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
992 messages::internalError(aResp->res);
993 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530994 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700995 BMCWEB_LOG_DEBUG << "Boot source update done.";
996 },
997 "xyz.openbmc_project.Settings", bootObj,
998 "org.freedesktop.DBus.Properties", "Set",
999 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1000 std::variant<std::string>(bootSourceStr));
1001
1002 crow::connections::systemBus->async_method_call(
1003 [aResp](const boost::system::error_code ec) {
1004 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301005 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001006 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1007 messages::internalError(aResp->res);
1008 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301009 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001010 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1011 },
1012 "xyz.openbmc_project.Settings", bootObj,
1013 "org.freedesktop.DBus.Properties", "Set",
1014 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1015 std::variant<std::string>(bootModeStr));
1016
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301017 crow::connections::systemBus->async_method_call(
1018 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1019 if (ec)
1020 {
1021 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1022 messages::internalError(aResp->res);
1023 return;
1024 }
1025 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1026 },
1027 "xyz.openbmc_project.Settings",
1028 "/xyz/openbmc_project/control/host0/boot/one_time",
1029 "org.freedesktop.DBus.Properties", "Set",
1030 "xyz.openbmc_project.Object.Enable", "Enabled",
1031 std::variant<bool>(oneTimeSetting));
1032}
1033
1034/**
1035 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1036 * set boot source/boot mode properties.
1037 *
1038 * @param[in] aResp Shared pointer for generating response message.
1039 * @param[in] bootSource The boot source from incoming RF request.
1040 * @param[in] bootEnable The boot override enable from incoming RF request.
1041 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001042 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301043 */
1044static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1045 std::optional<std::string> bootSource,
1046 std::optional<std::string> bootEnable)
1047{
1048 BMCWEB_LOG_DEBUG << "Set boot information.";
1049
1050 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001051 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301052 bootEnable{std::move(bootEnable)}](
1053 const boost::system::error_code ec,
1054 const sdbusplus::message::variant<bool> &oneTime) {
1055 if (ec)
1056 {
1057 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1058 messages::internalError(aResp->res);
1059 return;
1060 }
1061
1062 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1063
1064 if (!oneTimePtr)
1065 {
1066 messages::internalError(aResp->res);
1067 return;
1068 }
1069
1070 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1071
1072 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1073 std::move(bootEnable));
1074 },
1075 "xyz.openbmc_project.Settings",
1076 "/xyz/openbmc_project/control/host0/boot/one_time",
1077 "org.freedesktop.DBus.Properties", "Get",
1078 "xyz.openbmc_project.Object.Enable", "Enabled");
1079}
1080
AppaRao Pulia6349912019-10-18 17:16:08 +05301081#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1082/**
1083 * @brief Retrieves provisioning status
1084 *
1085 * @param[in] aResp Shared pointer for completing asynchronous calls.
1086 *
1087 * @return None.
1088 */
1089void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1090{
1091 BMCWEB_LOG_DEBUG << "Get OEM information.";
1092 crow::connections::systemBus->async_method_call(
1093 [aResp](const boost::system::error_code ec,
1094 const std::vector<std::pair<std::string, VariantType>>
1095 &propertiesList) {
1096 if (ec)
1097 {
1098 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1099 messages::internalError(aResp->res);
1100 return;
1101 }
1102
1103 const bool *provState = nullptr;
1104 const bool *lockState = nullptr;
1105 for (const std::pair<std::string, VariantType> &property :
1106 propertiesList)
1107 {
1108 if (property.first == "UfmProvisioned")
1109 {
1110 provState = std::get_if<bool>(&property.second);
1111 }
1112 else if (property.first == "UfmLocked")
1113 {
1114 lockState = std::get_if<bool>(&property.second);
1115 }
1116 }
1117
1118 if ((provState == nullptr) || (lockState == nullptr))
1119 {
1120 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1121 messages::internalError(aResp->res);
1122 return;
1123 }
1124
1125 nlohmann::json &oemPFR =
1126 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1127 if (*provState == true)
1128 {
1129 if (*lockState == true)
1130 {
1131 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1132 }
1133 else
1134 {
1135 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1136 }
1137 }
1138 else
1139 {
1140 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1141 }
1142 },
1143 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1144 "org.freedesktop.DBus.Properties", "GetAll",
1145 "xyz.openbmc_project.PFR.Attributes");
1146}
1147#endif
1148
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301149/**
Yong Li51709ff2019-09-30 14:13:04 +08001150 * @brief Translates watchdog timeout action DBUS property value to redfish.
1151 *
1152 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1153 *
1154 * @return Returns as a string, the timeout action in Redfish terms. If
1155 * translation cannot be done, returns an empty string.
1156 */
1157static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1158{
1159 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1160 {
1161 return "None";
1162 }
1163 else if (dbusAction ==
1164 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1165 {
1166 return "ResetSystem";
1167 }
1168 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1169 {
1170 return "PowerDown";
1171 }
1172 else if (dbusAction ==
1173 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1174 {
1175 return "PowerCycle";
1176 }
1177
1178 return "";
1179}
1180
1181/**
Yong Lic45f0082019-10-10 14:19:01 +08001182 *@brief Translates timeout action from Redfish to DBUS property value.
1183 *
1184 *@param[in] rfAction The timeout action in Redfish.
1185 *
1186 *@return Returns as a string, the time_out action as expected by DBUS.
1187 *If translation cannot be done, returns an empty string.
1188 */
1189
1190static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1191{
1192 if (rfAction == "None")
1193 {
1194 return "xyz.openbmc_project.State.Watchdog.Action.None";
1195 }
1196 else if (rfAction == "PowerCycle")
1197 {
1198 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1199 }
1200 else if (rfAction == "PowerDown")
1201 {
1202 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1203 }
1204 else if (rfAction == "ResetSystem")
1205 {
1206 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1207 }
1208
1209 return "";
1210}
1211
1212/**
Yong Li51709ff2019-09-30 14:13:04 +08001213 * @brief Retrieves host watchdog timer properties over DBUS
1214 *
1215 * @param[in] aResp Shared pointer for completing asynchronous calls.
1216 *
1217 * @return None.
1218 */
1219void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1220{
1221 BMCWEB_LOG_DEBUG << "Get host watchodg";
1222 crow::connections::systemBus->async_method_call(
1223 [aResp](const boost::system::error_code ec,
1224 PropertiesType &properties) {
1225 if (ec)
1226 {
1227 // watchdog service is stopped
1228 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1229 return;
1230 }
1231
1232 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1233
1234 nlohmann::json &hostWatchdogTimer =
1235 aResp->res.jsonValue["HostWatchdogTimer"];
1236
1237 // watchdog service is running/enabled
1238 hostWatchdogTimer["Status"]["State"] = "Enabled";
1239
1240 for (const auto &property : properties)
1241 {
1242 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1243 if (property.first == "Enabled")
1244 {
1245 const bool *state = std::get_if<bool>(&property.second);
1246
1247 if (!state)
1248 {
1249 messages::internalError(aResp->res);
1250 continue;
1251 }
1252
1253 hostWatchdogTimer["FunctionEnabled"] = *state;
1254 }
1255 else if (property.first == "ExpireAction")
1256 {
1257 const std::string *s =
1258 std::get_if<std::string>(&property.second);
1259 if (!s)
1260 {
1261 messages::internalError(aResp->res);
1262 continue;
1263 }
1264
1265 std::string action = dbusToRfWatchdogAction(*s);
1266 if (action.empty())
1267 {
1268 messages::internalError(aResp->res);
1269 continue;
1270 }
1271 hostWatchdogTimer["TimeoutAction"] = action;
1272 }
1273 }
1274 },
1275 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1276 "org.freedesktop.DBus.Properties", "GetAll",
1277 "xyz.openbmc_project.State.Watchdog");
1278}
1279
1280/**
Yong Lic45f0082019-10-10 14:19:01 +08001281 * @brief Sets Host WatchDog Timer properties.
1282 *
1283 * @param[in] aResp Shared pointer for generating response message.
1284 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1285 * RF request.
1286 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1287 *
1288 * @return None.
1289 */
1290static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1291 const std::optional<bool> wdtEnable,
1292 const std::optional<std::string> &wdtTimeOutAction)
1293{
1294 BMCWEB_LOG_DEBUG << "Set host watchdog";
1295
1296 if (wdtTimeOutAction)
1297 {
1298 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1299 // check if TimeOut Action is Valid
1300 if (wdtTimeOutActStr.empty())
1301 {
1302 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1303 << *wdtTimeOutAction;
1304 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1305 "TimeoutAction");
1306 return;
1307 }
1308
1309 crow::connections::systemBus->async_method_call(
1310 [aResp](const boost::system::error_code ec) {
1311 if (ec)
1312 {
1313 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1314 messages::internalError(aResp->res);
1315 return;
1316 }
1317 },
1318 "xyz.openbmc_project.Watchdog",
1319 "/xyz/openbmc_project/watchdog/host0",
1320 "org.freedesktop.DBus.Properties", "Set",
1321 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1322 std::variant<std::string>(wdtTimeOutActStr));
1323 }
1324
1325 if (wdtEnable)
1326 {
1327 crow::connections::systemBus->async_method_call(
1328 [aResp](const boost::system::error_code ec) {
1329 if (ec)
1330 {
1331 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1332 messages::internalError(aResp->res);
1333 return;
1334 }
1335 },
1336 "xyz.openbmc_project.Watchdog",
1337 "/xyz/openbmc_project/watchdog/host0",
1338 "org.freedesktop.DBus.Properties", "Set",
1339 "xyz.openbmc_project.State.Watchdog", "Enabled",
1340 std::variant<bool>(*wdtEnable));
1341 }
1342}
1343
1344/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001345 * SystemsCollection derived class for delivering ComputerSystems Collection
1346 * Schema
1347 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001348class SystemsCollection : public Node
1349{
1350 public:
1351 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1352 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001353 entityPrivileges = {
1354 {boost::beast::http::verb::get, {{"Login"}}},
1355 {boost::beast::http::verb::head, {{"Login"}}},
1356 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1357 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1358 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1359 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1360 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001361
Ed Tanous1abe55e2018-09-05 08:30:59 -07001362 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001363 void doGet(crow::Response &res, const crow::Request &req,
1364 const std::vector<std::string> &params) override
1365 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001366 res.jsonValue["@odata.type"] =
1367 "#ComputerSystemCollection.ComputerSystemCollection";
1368 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1369 res.jsonValue["@odata.context"] =
1370 "/redfish/v1/"
1371 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1372 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001373 res.jsonValue["Members"] = {
1374 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1375 res.jsonValue["Members@odata.count"] = 1;
1376 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001377 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001378};
1379
1380/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001381 * SystemActionsReset class supports handle POST method for Reset action.
1382 * The class retrieves and sends data directly to D-Bus.
1383 */
1384class SystemActionsReset : public Node
1385{
1386 public:
1387 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001388 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001389 {
1390 entityPrivileges = {
1391 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1392 }
1393
1394 private:
1395 /**
1396 * Function handles POST method request.
1397 * Analyzes POST body message before sends Reset request data to D-Bus.
1398 */
1399 void doPost(crow::Response &res, const crow::Request &req,
1400 const std::vector<std::string> &params) override
1401 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001402 auto asyncResp = std::make_shared<AsyncResp>(res);
1403
1404 std::string resetType;
1405 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001406 {
1407 return;
1408 }
1409
Jason M. Billsd22c8392019-06-03 13:59:03 -07001410 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001411 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001412 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001413 if (resetType == "On")
1414 {
1415 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001416 hostCommand = true;
1417 }
1418 else if (resetType == "ForceOff")
1419 {
1420 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1421 hostCommand = false;
1422 }
1423 else if (resetType == "ForceOn")
1424 {
1425 command = "xyz.openbmc_project.State.Host.Transition.On";
1426 hostCommand = true;
1427 }
1428 else if (resetType == "ForceRestart")
1429 {
1430 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1431 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001432 }
1433 else if (resetType == "GracefulShutdown")
1434 {
1435 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001436 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001437 }
1438 else if (resetType == "GracefulRestart")
1439 {
1440 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001441 hostCommand = true;
1442 }
1443 else if (resetType == "PowerCycle")
1444 {
1445 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1446 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001447 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001448 else if (resetType == "Nmi")
1449 {
1450 doNMI(asyncResp);
1451 return;
1452 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001453 else
1454 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001455 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001456 return;
1457 }
1458
Jason M. Billsd22c8392019-06-03 13:59:03 -07001459 if (hostCommand)
1460 {
1461 crow::connections::systemBus->async_method_call(
1462 [asyncResp, resetType](const boost::system::error_code ec) {
1463 if (ec)
1464 {
1465 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1466 if (ec.value() == boost::asio::error::invalid_argument)
1467 {
1468 messages::actionParameterNotSupported(
1469 asyncResp->res, resetType, "Reset");
1470 }
1471 else
1472 {
1473 messages::internalError(asyncResp->res);
1474 }
1475 return;
1476 }
1477 messages::success(asyncResp->res);
1478 },
1479 "xyz.openbmc_project.State.Host",
1480 "/xyz/openbmc_project/state/host0",
1481 "org.freedesktop.DBus.Properties", "Set",
1482 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1483 std::variant<std::string>{command});
1484 }
1485 else
1486 {
1487 crow::connections::systemBus->async_method_call(
1488 [asyncResp, resetType](const boost::system::error_code ec) {
1489 if (ec)
1490 {
1491 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1492 if (ec.value() == boost::asio::error::invalid_argument)
1493 {
1494 messages::actionParameterNotSupported(
1495 asyncResp->res, resetType, "Reset");
1496 }
1497 else
1498 {
1499 messages::internalError(asyncResp->res);
1500 }
1501 return;
1502 }
1503 messages::success(asyncResp->res);
1504 },
1505 "xyz.openbmc_project.State.Chassis",
1506 "/xyz/openbmc_project/state/chassis0",
1507 "org.freedesktop.DBus.Properties", "Set",
1508 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1509 std::variant<std::string>{command});
1510 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001511 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001512 /**
1513 * Function transceives data with dbus directly.
1514 */
1515 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1516 {
1517 constexpr char const *serviceName =
1518 "xyz.openbmc_project.Control.Host.NMI";
1519 constexpr char const *objectPath =
1520 "/xyz/openbmc_project/control/host0/nmi";
1521 constexpr char const *interfaceName =
1522 "xyz.openbmc_project.Control.Host.NMI";
1523 constexpr char const *method = "NMI";
1524
1525 crow::connections::systemBus->async_method_call(
1526 [asyncResp](const boost::system::error_code ec) {
1527 if (ec)
1528 {
1529 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1530 messages::internalError(asyncResp->res);
1531 return;
1532 }
1533 messages::success(asyncResp->res);
1534 },
1535 serviceName, objectPath, interfaceName, method);
1536 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001537};
1538
1539/**
Ed Tanous66173382018-08-15 18:20:59 -07001540 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001541 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001542class Systems : public Node
1543{
1544 public:
1545 /*
1546 * Default Constructor
1547 */
Ed Tanous029573d2019-02-01 10:57:49 -08001548 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001549 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001550 entityPrivileges = {
1551 {boost::beast::http::verb::get, {{"Login"}}},
1552 {boost::beast::http::verb::head, {{"Login"}}},
1553 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1554 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1555 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1556 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001557 }
1558
Ed Tanous1abe55e2018-09-05 08:30:59 -07001559 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001560 /**
1561 * Functions triggers appropriate requests on DBus
1562 */
1563 void doGet(crow::Response &res, const crow::Request &req,
1564 const std::vector<std::string> &params) override
1565 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301566 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001567 res.jsonValue["@odata.context"] =
1568 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001569 res.jsonValue["Name"] = "Computer System";
1570 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001571 res.jsonValue["SystemType"] = "Physical";
1572 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001573 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1574 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001575 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001576 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001577 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001578
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001579 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001580 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001581 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001582 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001583 res.jsonValue["Storage"] = {
1584 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001585
Ed Tanouscc340dd2018-08-29 13:43:38 -07001586 // TODO Need to support ForceRestart.
1587 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1588 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001589 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001590 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001591 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001592 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001593
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001594 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001595 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001596
Carol Wangd82a3ac2019-11-21 13:56:38 +08001597 res.jsonValue["Bios"] = {
1598 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1599
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001600 res.jsonValue["Links"]["ManagedBy"] = {
1601 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1602
1603 res.jsonValue["Status"] = {
1604 {"Health", "OK"},
1605 {"State", "Enabled"},
1606 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001607 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001608
James Feiste284a7c2019-11-20 16:20:23 -08001609 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001610 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001611 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001612 "xyz.openbmc_project.Inventory.Item.Drive",
1613 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001614
1615 auto health = std::make_shared<HealthPopulate>(asyncResp);
1616 crow::connections::systemBus->async_method_call(
1617 [health](const boost::system::error_code ec,
1618 std::vector<std::string> &resp) {
1619 if (ec)
1620 {
1621 // no inventory
1622 return;
1623 }
1624
1625 health->inventory = std::move(resp);
1626 },
1627 "xyz.openbmc_project.ObjectMapper",
1628 "/xyz/openbmc_project/object_mapper",
1629 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1630 int32_t(0), inventoryForSystems);
1631
1632 health->populate();
1633
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001634 getMainChassisId(asyncResp, [](const std::string &chassisId,
1635 std::shared_ptr<AsyncResp> aRsp) {
1636 aRsp->res.jsonValue["Links"]["Chassis"] = {
1637 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1638 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301639
1640 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001641 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001642 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301643 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001644 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001645 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301646#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1647 getProvisioningStatus(asyncResp);
1648#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001649 }
1650
Ed Tanous1abe55e2018-09-05 08:30:59 -07001651 void doPatch(crow::Response &res, const crow::Request &req,
1652 const std::vector<std::string> &params) override
1653 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301654 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301655 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001656 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001657 auto asyncResp = std::make_shared<AsyncResp>(res);
1658
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001659 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001660 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001661 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001662 return;
1663 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301664
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001665 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001666
1667 if (wdtTimerProps)
1668 {
1669 std::optional<bool> wdtEnable;
1670 std::optional<std::string> wdtTimeOutAction;
1671
1672 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1673 "FunctionEnabled", wdtEnable,
1674 "TimeoutAction", wdtTimeOutAction))
1675 {
1676 return;
1677 }
1678 setWDTProperties(asyncResp, std::move(wdtEnable),
1679 std::move(wdtTimeOutAction));
1680 }
1681
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301682 if (bootProps)
1683 {
1684 std::optional<std::string> bootSource;
1685 std::optional<std::string> bootEnable;
1686
1687 if (!json_util::readJson(*bootProps, asyncResp->res,
1688 "BootSourceOverrideTarget", bootSource,
1689 "BootSourceOverrideEnabled", bootEnable))
1690 {
1691 return;
1692 }
1693 setBootProperties(asyncResp, std::move(bootSource),
1694 std::move(bootEnable));
1695 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001696
Ed Tanous9712f8a2018-09-21 13:38:49 -07001697 if (indicatorLed)
1698 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301699 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001700 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001701 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001702};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001703} // namespace redfish