blob: 0aa0d6459d16477d78d26dccb014dd905e0851b8 [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 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500535
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600536 // Grab the bios version
537 fw_util::getActiveFwVersion(
538 aResp, fw_util::biosPurpose,
539 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800540 },
541 connection.first, path,
542 "org.freedesktop.DBus.Properties", "GetAll",
543 "xyz.openbmc_project.Inventory.Decorator."
544 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700545
546 crow::connections::systemBus->async_method_call(
547 [aResp](
548 const boost::system::error_code ec,
549 const std::variant<std::string> &property) {
550 if (ec)
551 {
552 // doesn't have to include this
553 // interface
554 return;
555 }
556
557 const std::string *value =
558 std::get_if<std::string>(&property);
559 if (value != nullptr)
560 {
561 aResp->res.jsonValue["AssetTag"] =
562 *value;
563 }
564 },
565 connection.first, path,
566 "org.freedesktop.DBus.Properties", "Get",
567 "xyz.openbmc_project.Inventory.Decorator."
568 "AssetTag",
569 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700570 }
571 }
572 }
573 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700574 },
575 "xyz.openbmc_project.ObjectMapper",
576 "/xyz/openbmc_project/object_mapper",
577 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700578 "/xyz/openbmc_project/inventory", int32_t(0),
579 std::array<const char *, 5>{
580 "xyz.openbmc_project.Inventory.Decorator.Asset",
581 "xyz.openbmc_project.Inventory.Item.Cpu",
582 "xyz.openbmc_project.Inventory.Item.Dimm",
583 "xyz.openbmc_project.Inventory.Item.System",
584 "xyz.openbmc_project.Common.UUID",
585 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700586}
587
588/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700589 * @brief Retrieves host state properties over dbus
590 *
591 * @param[in] aResp Shared pointer for completing asynchronous calls.
592 *
593 * @return None.
594 */
595void getHostState(std::shared_ptr<AsyncResp> aResp)
596{
597 BMCWEB_LOG_DEBUG << "Get host information.";
598 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800599 [aResp](const boost::system::error_code ec,
600 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700601 if (ec)
602 {
603 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700604 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700605 return;
606 }
Ed Tanous66173382018-08-15 18:20:59 -0700607
Ed Tanousabf2add2019-01-22 16:40:12 -0800608 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700609 BMCWEB_LOG_DEBUG << "Host state: " << *s;
610 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700611 {
Ed Tanous66173382018-08-15 18:20:59 -0700612 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800613 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700614 {
Ed Tanous66173382018-08-15 18:20:59 -0700615 aResp->res.jsonValue["PowerState"] = "On";
616 aResp->res.jsonValue["Status"]["State"] = "Enabled";
617 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600618 else if (*s == "xyz.openbmc_project.State.Host.HostState."
619 "DiagnosticMode")
620 {
621 aResp->res.jsonValue["PowerState"] = "On";
622 aResp->res.jsonValue["Status"]["State"] = "InTest";
623 }
Ed Tanous66173382018-08-15 18:20:59 -0700624 else
625 {
626 aResp->res.jsonValue["PowerState"] = "Off";
627 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700628 }
629 }
630 },
631 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700632 "org.freedesktop.DBus.Properties", "Get",
633 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700634}
635
636/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530637 * @brief Traslates boot source DBUS property value to redfish.
638 *
639 * @param[in] dbusSource The boot source in DBUS speak.
640 *
641 * @return Returns as a string, the boot source in Redfish terms. If translation
642 * cannot be done, returns an empty string.
643 */
644static std::string dbusToRfBootSource(const std::string &dbusSource)
645{
646 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
647 {
648 return "None";
649 }
650 else if (dbusSource ==
651 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
652 {
653 return "Hdd";
654 }
655 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530656 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530657 {
658 return "Cd";
659 }
660 else if (dbusSource ==
661 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
662 {
663 return "Pxe";
664 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700665 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700666 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700667 {
668 return "Usb";
669 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530670 else
671 {
672 return "";
673 }
674}
675
676/**
677 * @brief Traslates boot mode DBUS property value to redfish.
678 *
679 * @param[in] dbusMode The boot mode in DBUS speak.
680 *
681 * @return Returns as a string, the boot mode in Redfish terms. If translation
682 * cannot be done, returns an empty string.
683 */
684static std::string dbusToRfBootMode(const std::string &dbusMode)
685{
686 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
687 {
688 return "None";
689 }
690 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
691 {
692 return "Diags";
693 }
694 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
695 {
696 return "BiosSetup";
697 }
698 else
699 {
700 return "";
701 }
702}
703
704/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700705 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530706 *
707 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700708 * @param[out] bootSource The DBus source
709 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530710 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700711 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700713static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
714 const std::string &rfSource,
715 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530716{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700717 // The caller has initialized the bootSource and bootMode to:
718 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
719 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
720 // Only modify the bootSource/bootMode variable needed to achieve the
721 // desired boot action.
722
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530723 if (rfSource == "None")
724 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700725 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530726 }
727 else if (rfSource == "Pxe")
728 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700729 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
730 }
731 else if (rfSource == "Hdd")
732 {
733 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
734 }
735 else if (rfSource == "Diags")
736 {
737 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
738 }
739 else if (rfSource == "Cd")
740 {
741 bootSource =
742 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
743 }
744 else if (rfSource == "BiosSetup")
745 {
746 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530747 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700748 else if (rfSource == "Usb")
749 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700750 bootSource =
751 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700752 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530753 else
754 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700755 BMCWEB_LOG_DEBUG << "Invalid property value for "
756 "BootSourceOverrideTarget: "
757 << bootSource;
758 messages::propertyValueNotInList(aResp->res, rfSource,
759 "BootSourceTargetOverride");
760 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530761 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700762 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530763}
764
765/**
766 * @brief Retrieves boot mode over DBUS and fills out the response
767 *
768 * @param[in] aResp Shared pointer for generating response message.
769 * @param[in] bootDbusObj The dbus object to query for boot properties.
770 *
771 * @return None.
772 */
773static void getBootMode(std::shared_ptr<AsyncResp> aResp,
774 std::string bootDbusObj)
775{
776 crow::connections::systemBus->async_method_call(
777 [aResp](const boost::system::error_code ec,
778 const std::variant<std::string> &bootMode) {
779 if (ec)
780 {
781 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
782 messages::internalError(aResp->res);
783 return;
784 }
785
786 const std::string *bootModeStr =
787 std::get_if<std::string>(&bootMode);
788
789 if (!bootModeStr)
790 {
791 messages::internalError(aResp->res);
792 return;
793 }
794
795 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
796
797 // TODO (Santosh): Do we need to support override mode?
798 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
799 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
800 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700801 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530802
803 if (*bootModeStr !=
804 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
805 {
806 auto rfMode = dbusToRfBootMode(*bootModeStr);
807 if (!rfMode.empty())
808 {
809 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
810 rfMode;
811 }
812 }
813
814 // If the BootSourceOverrideTarget is still "None" at the end,
815 // reset the BootSourceOverrideEnabled to indicate that
816 // overrides are disabled
817 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
818 "None")
819 {
820 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
821 "Disabled";
822 }
823 },
824 "xyz.openbmc_project.Settings", bootDbusObj,
825 "org.freedesktop.DBus.Properties", "Get",
826 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
827}
828
829/**
830 * @brief Retrieves boot source over DBUS
831 *
832 * @param[in] aResp Shared pointer for generating response message.
833 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
834 *
835 * @return None.
836 */
837static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
838{
839 std::string bootDbusObj =
840 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
841 : "/xyz/openbmc_project/control/host0/boot";
842
843 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
844 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
845 (oneTimeEnabled) ? "Once" : "Continuous";
846
847 crow::connections::systemBus->async_method_call(
848 [aResp, bootDbusObj](const boost::system::error_code ec,
849 const std::variant<std::string> &bootSource) {
850 if (ec)
851 {
852 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
853 messages::internalError(aResp->res);
854 return;
855 }
856
857 const std::string *bootSourceStr =
858 std::get_if<std::string>(&bootSource);
859
860 if (!bootSourceStr)
861 {
862 messages::internalError(aResp->res);
863 return;
864 }
865 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
866
867 auto rfSource = dbusToRfBootSource(*bootSourceStr);
868 if (!rfSource.empty())
869 {
870 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
871 rfSource;
872 }
873 },
874 "xyz.openbmc_project.Settings", bootDbusObj,
875 "org.freedesktop.DBus.Properties", "Get",
876 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
877 getBootMode(std::move(aResp), std::move(bootDbusObj));
878}
879
880/**
881 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
882 * get boot source and boot mode.
883 *
884 * @param[in] aResp Shared pointer for generating response message.
885 *
886 * @return None.
887 */
888static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
889{
890 BMCWEB_LOG_DEBUG << "Get boot information.";
891
892 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800893 [aResp](const boost::system::error_code ec,
894 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530895 if (ec)
896 {
897 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700898 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530899 return;
900 }
901
902 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
903
904 if (!oneTimePtr)
905 {
906 messages::internalError(aResp->res);
907 return;
908 }
909 getBootSource(aResp, *oneTimePtr);
910 },
911 "xyz.openbmc_project.Settings",
912 "/xyz/openbmc_project/control/host0/boot/one_time",
913 "org.freedesktop.DBus.Properties", "Get",
914 "xyz.openbmc_project.Object.Enable", "Enabled");
915}
916
917/**
918 * @brief Sets boot properties into DBUS object(s).
919 *
920 * @param[in] aResp Shared pointer for generating response message.
921 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
922 * @param[in] bootSource The boot source to set.
923 * @param[in] bootEnable The source override "enable" to set.
924 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700925 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530926 */
927static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
928 bool oneTimeEnabled,
929 std::optional<std::string> bootSource,
930 std::optional<std::string> bootEnable)
931{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700932 std::string bootSourceStr =
933 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
934 std::string bootModeStr =
935 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530936 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700937 bool useBootSource = true;
938
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530939 // Validate incoming parameters
940 if (bootEnable)
941 {
942 if (*bootEnable == "Once")
943 {
944 oneTimeSetting = true;
945 }
946 else if (*bootEnable == "Continuous")
947 {
948 oneTimeSetting = false;
949 }
950 else if (*bootEnable == "Disabled")
951 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700952 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530953 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700954 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530955 }
956 else
957 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530958 BMCWEB_LOG_DEBUG << "Unsupported value for "
959 "BootSourceOverrideEnabled: "
960 << *bootEnable;
961 messages::propertyValueNotInList(aResp->res, *bootEnable,
962 "BootSourceOverrideEnabled");
963 return;
964 }
965 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530966
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700967 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530968 {
969 // Source target specified
970 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
971 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700972 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
973 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700975 BMCWEB_LOG_DEBUG
976 << "Invalid property value for BootSourceOverrideTarget: "
977 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530978 messages::propertyValueNotInList(aResp->res, *bootSource,
979 "BootSourceTargetOverride");
980 return;
981 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700982 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530983
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700984 // Act on validated parameters
985 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
986 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
987 const char *bootObj =
988 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
989 : "/xyz/openbmc_project/control/host0/boot";
990
991 crow::connections::systemBus->async_method_call(
992 [aResp](const boost::system::error_code ec) {
993 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530994 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700995 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
996 messages::internalError(aResp->res);
997 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530998 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700999 BMCWEB_LOG_DEBUG << "Boot source update done.";
1000 },
1001 "xyz.openbmc_project.Settings", bootObj,
1002 "org.freedesktop.DBus.Properties", "Set",
1003 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1004 std::variant<std::string>(bootSourceStr));
1005
1006 crow::connections::systemBus->async_method_call(
1007 [aResp](const boost::system::error_code ec) {
1008 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301009 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001010 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1011 messages::internalError(aResp->res);
1012 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301013 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001014 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1015 },
1016 "xyz.openbmc_project.Settings", bootObj,
1017 "org.freedesktop.DBus.Properties", "Set",
1018 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1019 std::variant<std::string>(bootModeStr));
1020
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301021 crow::connections::systemBus->async_method_call(
1022 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1023 if (ec)
1024 {
1025 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1026 messages::internalError(aResp->res);
1027 return;
1028 }
1029 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1030 },
1031 "xyz.openbmc_project.Settings",
1032 "/xyz/openbmc_project/control/host0/boot/one_time",
1033 "org.freedesktop.DBus.Properties", "Set",
1034 "xyz.openbmc_project.Object.Enable", "Enabled",
1035 std::variant<bool>(oneTimeSetting));
1036}
1037
1038/**
1039 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1040 * set boot source/boot mode properties.
1041 *
1042 * @param[in] aResp Shared pointer for generating response message.
1043 * @param[in] bootSource The boot source from incoming RF request.
1044 * @param[in] bootEnable The boot override enable from incoming RF request.
1045 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001046 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301047 */
1048static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1049 std::optional<std::string> bootSource,
1050 std::optional<std::string> bootEnable)
1051{
1052 BMCWEB_LOG_DEBUG << "Set boot information.";
1053
1054 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001055 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301056 bootEnable{std::move(bootEnable)}](
1057 const boost::system::error_code ec,
1058 const sdbusplus::message::variant<bool> &oneTime) {
1059 if (ec)
1060 {
1061 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1062 messages::internalError(aResp->res);
1063 return;
1064 }
1065
1066 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1067
1068 if (!oneTimePtr)
1069 {
1070 messages::internalError(aResp->res);
1071 return;
1072 }
1073
1074 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1075
1076 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1077 std::move(bootEnable));
1078 },
1079 "xyz.openbmc_project.Settings",
1080 "/xyz/openbmc_project/control/host0/boot/one_time",
1081 "org.freedesktop.DBus.Properties", "Get",
1082 "xyz.openbmc_project.Object.Enable", "Enabled");
1083}
1084
AppaRao Pulia6349912019-10-18 17:16:08 +05301085#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1086/**
1087 * @brief Retrieves provisioning status
1088 *
1089 * @param[in] aResp Shared pointer for completing asynchronous calls.
1090 *
1091 * @return None.
1092 */
1093void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1094{
1095 BMCWEB_LOG_DEBUG << "Get OEM information.";
1096 crow::connections::systemBus->async_method_call(
1097 [aResp](const boost::system::error_code ec,
1098 const std::vector<std::pair<std::string, VariantType>>
1099 &propertiesList) {
1100 if (ec)
1101 {
1102 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1103 messages::internalError(aResp->res);
1104 return;
1105 }
1106
1107 const bool *provState = nullptr;
1108 const bool *lockState = nullptr;
1109 for (const std::pair<std::string, VariantType> &property :
1110 propertiesList)
1111 {
1112 if (property.first == "UfmProvisioned")
1113 {
1114 provState = std::get_if<bool>(&property.second);
1115 }
1116 else if (property.first == "UfmLocked")
1117 {
1118 lockState = std::get_if<bool>(&property.second);
1119 }
1120 }
1121
1122 if ((provState == nullptr) || (lockState == nullptr))
1123 {
1124 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1125 messages::internalError(aResp->res);
1126 return;
1127 }
1128
1129 nlohmann::json &oemPFR =
1130 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1131 if (*provState == true)
1132 {
1133 if (*lockState == true)
1134 {
1135 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1136 }
1137 else
1138 {
1139 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1140 }
1141 }
1142 else
1143 {
1144 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1145 }
1146 },
1147 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1148 "org.freedesktop.DBus.Properties", "GetAll",
1149 "xyz.openbmc_project.PFR.Attributes");
1150}
1151#endif
1152
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301153/**
Yong Li51709ff2019-09-30 14:13:04 +08001154 * @brief Translates watchdog timeout action DBUS property value to redfish.
1155 *
1156 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1157 *
1158 * @return Returns as a string, the timeout action in Redfish terms. If
1159 * translation cannot be done, returns an empty string.
1160 */
1161static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1162{
1163 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1164 {
1165 return "None";
1166 }
1167 else if (dbusAction ==
1168 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1169 {
1170 return "ResetSystem";
1171 }
1172 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1173 {
1174 return "PowerDown";
1175 }
1176 else if (dbusAction ==
1177 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1178 {
1179 return "PowerCycle";
1180 }
1181
1182 return "";
1183}
1184
1185/**
Yong Lic45f0082019-10-10 14:19:01 +08001186 *@brief Translates timeout action from Redfish to DBUS property value.
1187 *
1188 *@param[in] rfAction The timeout action in Redfish.
1189 *
1190 *@return Returns as a string, the time_out action as expected by DBUS.
1191 *If translation cannot be done, returns an empty string.
1192 */
1193
1194static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1195{
1196 if (rfAction == "None")
1197 {
1198 return "xyz.openbmc_project.State.Watchdog.Action.None";
1199 }
1200 else if (rfAction == "PowerCycle")
1201 {
1202 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1203 }
1204 else if (rfAction == "PowerDown")
1205 {
1206 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1207 }
1208 else if (rfAction == "ResetSystem")
1209 {
1210 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1211 }
1212
1213 return "";
1214}
1215
1216/**
Yong Li51709ff2019-09-30 14:13:04 +08001217 * @brief Retrieves host watchdog timer properties over DBUS
1218 *
1219 * @param[in] aResp Shared pointer for completing asynchronous calls.
1220 *
1221 * @return None.
1222 */
1223void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1224{
1225 BMCWEB_LOG_DEBUG << "Get host watchodg";
1226 crow::connections::systemBus->async_method_call(
1227 [aResp](const boost::system::error_code ec,
1228 PropertiesType &properties) {
1229 if (ec)
1230 {
1231 // watchdog service is stopped
1232 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1233 return;
1234 }
1235
1236 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1237
1238 nlohmann::json &hostWatchdogTimer =
1239 aResp->res.jsonValue["HostWatchdogTimer"];
1240
1241 // watchdog service is running/enabled
1242 hostWatchdogTimer["Status"]["State"] = "Enabled";
1243
1244 for (const auto &property : properties)
1245 {
1246 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1247 if (property.first == "Enabled")
1248 {
1249 const bool *state = std::get_if<bool>(&property.second);
1250
1251 if (!state)
1252 {
1253 messages::internalError(aResp->res);
1254 continue;
1255 }
1256
1257 hostWatchdogTimer["FunctionEnabled"] = *state;
1258 }
1259 else if (property.first == "ExpireAction")
1260 {
1261 const std::string *s =
1262 std::get_if<std::string>(&property.second);
1263 if (!s)
1264 {
1265 messages::internalError(aResp->res);
1266 continue;
1267 }
1268
1269 std::string action = dbusToRfWatchdogAction(*s);
1270 if (action.empty())
1271 {
1272 messages::internalError(aResp->res);
1273 continue;
1274 }
1275 hostWatchdogTimer["TimeoutAction"] = action;
1276 }
1277 }
1278 },
1279 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1280 "org.freedesktop.DBus.Properties", "GetAll",
1281 "xyz.openbmc_project.State.Watchdog");
1282}
1283
1284/**
Yong Lic45f0082019-10-10 14:19:01 +08001285 * @brief Sets Host WatchDog Timer properties.
1286 *
1287 * @param[in] aResp Shared pointer for generating response message.
1288 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1289 * RF request.
1290 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1291 *
1292 * @return None.
1293 */
1294static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1295 const std::optional<bool> wdtEnable,
1296 const std::optional<std::string> &wdtTimeOutAction)
1297{
1298 BMCWEB_LOG_DEBUG << "Set host watchdog";
1299
1300 if (wdtTimeOutAction)
1301 {
1302 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1303 // check if TimeOut Action is Valid
1304 if (wdtTimeOutActStr.empty())
1305 {
1306 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1307 << *wdtTimeOutAction;
1308 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1309 "TimeoutAction");
1310 return;
1311 }
1312
1313 crow::connections::systemBus->async_method_call(
1314 [aResp](const boost::system::error_code ec) {
1315 if (ec)
1316 {
1317 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1318 messages::internalError(aResp->res);
1319 return;
1320 }
1321 },
1322 "xyz.openbmc_project.Watchdog",
1323 "/xyz/openbmc_project/watchdog/host0",
1324 "org.freedesktop.DBus.Properties", "Set",
1325 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1326 std::variant<std::string>(wdtTimeOutActStr));
1327 }
1328
1329 if (wdtEnable)
1330 {
1331 crow::connections::systemBus->async_method_call(
1332 [aResp](const boost::system::error_code ec) {
1333 if (ec)
1334 {
1335 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1336 messages::internalError(aResp->res);
1337 return;
1338 }
1339 },
1340 "xyz.openbmc_project.Watchdog",
1341 "/xyz/openbmc_project/watchdog/host0",
1342 "org.freedesktop.DBus.Properties", "Set",
1343 "xyz.openbmc_project.State.Watchdog", "Enabled",
1344 std::variant<bool>(*wdtEnable));
1345 }
1346}
1347
1348/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001349 * SystemsCollection derived class for delivering ComputerSystems Collection
1350 * Schema
1351 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001352class SystemsCollection : public Node
1353{
1354 public:
1355 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1356 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001357 entityPrivileges = {
1358 {boost::beast::http::verb::get, {{"Login"}}},
1359 {boost::beast::http::verb::head, {{"Login"}}},
1360 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1361 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1362 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1363 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1364 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001365
Ed Tanous1abe55e2018-09-05 08:30:59 -07001366 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001367 void doGet(crow::Response &res, const crow::Request &req,
1368 const std::vector<std::string> &params) override
1369 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001370 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001371 res.jsonValue["@odata.type"] =
1372 "#ComputerSystemCollection.ComputerSystemCollection";
1373 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001374 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001375
1376 crow::connections::systemBus->async_method_call(
1377 [asyncResp](const boost::system::error_code ec,
1378 const std::variant<std::string> &hostName) {
1379 nlohmann::json &iface_array =
1380 asyncResp->res.jsonValue["Members"];
1381 iface_array = nlohmann::json::array();
1382 auto &count = asyncResp->res.jsonValue["Members@odata.count"];
1383 count = 0;
1384 if (ec)
1385 {
1386 iface_array.push_back(
1387 {{"@odata.id", "/redfish/v1/Systems/system"}});
1388 count = iface_array.size();
1389 return;
1390 }
1391 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1392 iface_array.push_back(
1393 {{"@odata.id", "/redfish/v1/Systems/system"}});
1394 iface_array.push_back(
1395 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1396 count = iface_array.size();
1397 },
1398 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/vmi",
1399 "org.freedesktop.DBus.Properties", "Get",
1400 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001401 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001402};
1403
1404/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001405 * SystemActionsReset class supports handle POST method for Reset action.
1406 * The class retrieves and sends data directly to D-Bus.
1407 */
1408class SystemActionsReset : public Node
1409{
1410 public:
1411 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001412 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001413 {
1414 entityPrivileges = {
1415 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1416 }
1417
1418 private:
1419 /**
1420 * Function handles POST method request.
1421 * Analyzes POST body message before sends Reset request data to D-Bus.
1422 */
1423 void doPost(crow::Response &res, const crow::Request &req,
1424 const std::vector<std::string> &params) override
1425 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001426 auto asyncResp = std::make_shared<AsyncResp>(res);
1427
1428 std::string resetType;
1429 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001430 {
1431 return;
1432 }
1433
Jason M. Billsd22c8392019-06-03 13:59:03 -07001434 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001435 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001436 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001437 if (resetType == "On")
1438 {
1439 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001440 hostCommand = true;
1441 }
1442 else if (resetType == "ForceOff")
1443 {
1444 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1445 hostCommand = false;
1446 }
1447 else if (resetType == "ForceOn")
1448 {
1449 command = "xyz.openbmc_project.State.Host.Transition.On";
1450 hostCommand = true;
1451 }
1452 else if (resetType == "ForceRestart")
1453 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001454 command =
1455 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1456 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001457 }
1458 else if (resetType == "GracefulShutdown")
1459 {
1460 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001461 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001462 }
1463 else if (resetType == "GracefulRestart")
1464 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001465 command =
1466 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001467 hostCommand = true;
1468 }
1469 else if (resetType == "PowerCycle")
1470 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001471 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1472 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001473 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001474 else if (resetType == "Nmi")
1475 {
1476 doNMI(asyncResp);
1477 return;
1478 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001479 else
1480 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001481 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001482 return;
1483 }
1484
Jason M. Billsd22c8392019-06-03 13:59:03 -07001485 if (hostCommand)
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.Host",
1506 "/xyz/openbmc_project/state/host0",
1507 "org.freedesktop.DBus.Properties", "Set",
1508 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1509 std::variant<std::string>{command});
1510 }
1511 else
1512 {
1513 crow::connections::systemBus->async_method_call(
1514 [asyncResp, resetType](const boost::system::error_code ec) {
1515 if (ec)
1516 {
1517 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1518 if (ec.value() == boost::asio::error::invalid_argument)
1519 {
1520 messages::actionParameterNotSupported(
1521 asyncResp->res, resetType, "Reset");
1522 }
1523 else
1524 {
1525 messages::internalError(asyncResp->res);
1526 }
1527 return;
1528 }
1529 messages::success(asyncResp->res);
1530 },
1531 "xyz.openbmc_project.State.Chassis",
1532 "/xyz/openbmc_project/state/chassis0",
1533 "org.freedesktop.DBus.Properties", "Set",
1534 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1535 std::variant<std::string>{command});
1536 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001537 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001538 /**
1539 * Function transceives data with dbus directly.
1540 */
1541 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1542 {
1543 constexpr char const *serviceName =
1544 "xyz.openbmc_project.Control.Host.NMI";
1545 constexpr char const *objectPath =
1546 "/xyz/openbmc_project/control/host0/nmi";
1547 constexpr char const *interfaceName =
1548 "xyz.openbmc_project.Control.Host.NMI";
1549 constexpr char const *method = "NMI";
1550
1551 crow::connections::systemBus->async_method_call(
1552 [asyncResp](const boost::system::error_code ec) {
1553 if (ec)
1554 {
1555 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1556 messages::internalError(asyncResp->res);
1557 return;
1558 }
1559 messages::success(asyncResp->res);
1560 },
1561 serviceName, objectPath, interfaceName, method);
1562 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001563};
1564
1565/**
Ed Tanous66173382018-08-15 18:20:59 -07001566 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001567 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001568class Systems : public Node
1569{
1570 public:
1571 /*
1572 * Default Constructor
1573 */
Ed Tanous029573d2019-02-01 10:57:49 -08001574 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001575 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001576 entityPrivileges = {
1577 {boost::beast::http::verb::get, {{"Login"}}},
1578 {boost::beast::http::verb::head, {{"Login"}}},
1579 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1580 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1581 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1582 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001583 }
1584
Ed Tanous1abe55e2018-09-05 08:30:59 -07001585 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001586 /**
1587 * Functions triggers appropriate requests on DBus
1588 */
1589 void doGet(crow::Response &res, const crow::Request &req,
1590 const std::vector<std::string> &params) override
1591 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301592 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001593 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001594 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001595 res.jsonValue["SystemType"] = "Physical";
1596 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001597 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1598 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001599 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001600 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001601 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001602
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001603 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001604 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001605 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001606 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001607 res.jsonValue["Storage"] = {
1608 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001609
Ed Tanouscc340dd2018-08-29 13:43:38 -07001610 // TODO Need to support ForceRestart.
1611 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1612 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001613 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001614 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001615 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001616 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001617
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001618 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001619 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001620
Carol Wangd82a3ac2019-11-21 13:56:38 +08001621 res.jsonValue["Bios"] = {
1622 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1623
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001624 res.jsonValue["Links"]["ManagedBy"] = {
1625 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1626
1627 res.jsonValue["Status"] = {
1628 {"Health", "OK"},
1629 {"State", "Enabled"},
1630 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001631 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001632
James Feiste284a7c2019-11-20 16:20:23 -08001633 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001634 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001635 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001636 "xyz.openbmc_project.Inventory.Item.Drive",
1637 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001638
1639 auto health = std::make_shared<HealthPopulate>(asyncResp);
1640 crow::connections::systemBus->async_method_call(
1641 [health](const boost::system::error_code ec,
1642 std::vector<std::string> &resp) {
1643 if (ec)
1644 {
1645 // no inventory
1646 return;
1647 }
1648
1649 health->inventory = std::move(resp);
1650 },
1651 "xyz.openbmc_project.ObjectMapper",
1652 "/xyz/openbmc_project/object_mapper",
1653 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1654 int32_t(0), inventoryForSystems);
1655
1656 health->populate();
1657
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001658 getMainChassisId(asyncResp, [](const std::string &chassisId,
1659 std::shared_ptr<AsyncResp> aRsp) {
1660 aRsp->res.jsonValue["Links"]["Chassis"] = {
1661 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1662 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301663
1664 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001665 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001666 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301667 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001668 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001669 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301670#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1671 getProvisioningStatus(asyncResp);
1672#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001673 }
1674
Ed Tanous1abe55e2018-09-05 08:30:59 -07001675 void doPatch(crow::Response &res, const crow::Request &req,
1676 const std::vector<std::string> &params) override
1677 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301678 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301679 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001680 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001681 auto asyncResp = std::make_shared<AsyncResp>(res);
1682
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001683 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001684 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001685 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001686 return;
1687 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301688
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001689 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001690
1691 if (wdtTimerProps)
1692 {
1693 std::optional<bool> wdtEnable;
1694 std::optional<std::string> wdtTimeOutAction;
1695
1696 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1697 "FunctionEnabled", wdtEnable,
1698 "TimeoutAction", wdtTimeOutAction))
1699 {
1700 return;
1701 }
1702 setWDTProperties(asyncResp, std::move(wdtEnable),
1703 std::move(wdtTimeOutAction));
1704 }
1705
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301706 if (bootProps)
1707 {
1708 std::optional<std::string> bootSource;
1709 std::optional<std::string> bootEnable;
1710
1711 if (!json_util::readJson(*bootProps, asyncResp->res,
1712 "BootSourceOverrideTarget", bootSource,
1713 "BootSourceOverrideEnabled", bootEnable))
1714 {
1715 return;
1716 }
1717 setBootProperties(asyncResp, std::move(bootSource),
1718 std::move(bootEnable));
1719 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001720
Ed Tanous9712f8a2018-09-21 13:38:49 -07001721 if (indicatorLed)
1722 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301723 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001724 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001725 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001726};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001727} // namespace redfish