blob: a6928ca7143c0f3f06ac9ced85ebc0ff317e22e4 [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/**
George Liuc6a620f2020-04-10 17:18:11 +0800918 * @brief Retrieves power restore policy over DBUS.
919 *
920 * @param[in] aResp Shared pointer for generating response message.
921 *
922 * @return None.
923 */
924void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
925{
926 BMCWEB_LOG_DEBUG << "Get power restore policy";
927
928 crow::connections::systemBus->async_method_call(
929 [aResp](const boost::system::error_code ec,
930 sdbusplus::message::variant<std::string> &policy) {
931 if (ec)
932 {
933 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
934 return;
935 }
936
937 const boost::container::flat_map<std::string, std::string>
938 policyMaps = {
939 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
940 "AlwaysOn",
941 "AlwaysOn"},
942 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
943 "AlwaysOff",
944 "AlwaysOff"},
945 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
946 "LastState",
947 "LastState"}};
948
949 const std::string *policyPtr = std::get_if<std::string>(&policy);
950
951 if (!policyPtr)
952 {
953 messages::internalError(aResp->res);
954 return;
955 }
956
957 auto policyMapsIt = policyMaps.find(*policyPtr);
958 if (policyMapsIt == policyMaps.end())
959 {
960 messages::internalError(aResp->res);
961 return;
962 }
963
964 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
965 },
966 "xyz.openbmc_project.Settings",
967 "/xyz/openbmc_project/control/host0/power_restore_policy",
968 "org.freedesktop.DBus.Properties", "Get",
969 "xyz.openbmc_project.Control.Power.RestorePolicy",
970 "PowerRestorePolicy");
971}
972
973/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974 * @brief Sets boot properties into DBUS object(s).
975 *
976 * @param[in] aResp Shared pointer for generating response message.
977 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
978 * @param[in] bootSource The boot source to set.
979 * @param[in] bootEnable The source override "enable" to set.
980 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700981 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530982 */
983static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
984 bool oneTimeEnabled,
985 std::optional<std::string> bootSource,
986 std::optional<std::string> bootEnable)
987{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700988 std::string bootSourceStr =
989 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
990 std::string bootModeStr =
991 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530992 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700993 bool useBootSource = true;
994
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530995 // Validate incoming parameters
996 if (bootEnable)
997 {
998 if (*bootEnable == "Once")
999 {
1000 oneTimeSetting = true;
1001 }
1002 else if (*bootEnable == "Continuous")
1003 {
1004 oneTimeSetting = false;
1005 }
1006 else if (*bootEnable == "Disabled")
1007 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001008 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301009 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001010 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301011 }
1012 else
1013 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301014 BMCWEB_LOG_DEBUG << "Unsupported value for "
1015 "BootSourceOverrideEnabled: "
1016 << *bootEnable;
1017 messages::propertyValueNotInList(aResp->res, *bootEnable,
1018 "BootSourceOverrideEnabled");
1019 return;
1020 }
1021 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301022
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001023 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024 {
1025 // Source target specified
1026 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1027 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001028 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1029 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001031 BMCWEB_LOG_DEBUG
1032 << "Invalid property value for BootSourceOverrideTarget: "
1033 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301034 messages::propertyValueNotInList(aResp->res, *bootSource,
1035 "BootSourceTargetOverride");
1036 return;
1037 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001038 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301039
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001040 // Act on validated parameters
1041 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1042 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1043 const char *bootObj =
1044 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1045 : "/xyz/openbmc_project/control/host0/boot";
1046
1047 crow::connections::systemBus->async_method_call(
1048 [aResp](const boost::system::error_code ec) {
1049 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301050 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001051 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1052 messages::internalError(aResp->res);
1053 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301054 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001055 BMCWEB_LOG_DEBUG << "Boot source update done.";
1056 },
1057 "xyz.openbmc_project.Settings", bootObj,
1058 "org.freedesktop.DBus.Properties", "Set",
1059 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1060 std::variant<std::string>(bootSourceStr));
1061
1062 crow::connections::systemBus->async_method_call(
1063 [aResp](const boost::system::error_code ec) {
1064 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301065 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001066 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1067 messages::internalError(aResp->res);
1068 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301069 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001070 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1071 },
1072 "xyz.openbmc_project.Settings", bootObj,
1073 "org.freedesktop.DBus.Properties", "Set",
1074 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1075 std::variant<std::string>(bootModeStr));
1076
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301077 crow::connections::systemBus->async_method_call(
1078 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1079 if (ec)
1080 {
1081 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1082 messages::internalError(aResp->res);
1083 return;
1084 }
1085 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1086 },
1087 "xyz.openbmc_project.Settings",
1088 "/xyz/openbmc_project/control/host0/boot/one_time",
1089 "org.freedesktop.DBus.Properties", "Set",
1090 "xyz.openbmc_project.Object.Enable", "Enabled",
1091 std::variant<bool>(oneTimeSetting));
1092}
1093
1094/**
1095 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1096 * set boot source/boot mode properties.
1097 *
1098 * @param[in] aResp Shared pointer for generating response message.
1099 * @param[in] bootSource The boot source from incoming RF request.
1100 * @param[in] bootEnable The boot override enable from incoming RF request.
1101 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001102 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301103 */
1104static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1105 std::optional<std::string> bootSource,
1106 std::optional<std::string> bootEnable)
1107{
1108 BMCWEB_LOG_DEBUG << "Set boot information.";
1109
1110 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001111 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301112 bootEnable{std::move(bootEnable)}](
1113 const boost::system::error_code ec,
1114 const sdbusplus::message::variant<bool> &oneTime) {
1115 if (ec)
1116 {
1117 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1118 messages::internalError(aResp->res);
1119 return;
1120 }
1121
1122 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1123
1124 if (!oneTimePtr)
1125 {
1126 messages::internalError(aResp->res);
1127 return;
1128 }
1129
1130 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1131
1132 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1133 std::move(bootEnable));
1134 },
1135 "xyz.openbmc_project.Settings",
1136 "/xyz/openbmc_project/control/host0/boot/one_time",
1137 "org.freedesktop.DBus.Properties", "Get",
1138 "xyz.openbmc_project.Object.Enable", "Enabled");
1139}
1140
George Liuc6a620f2020-04-10 17:18:11 +08001141/**
1142 * @brief Sets power restore policy properties.
1143 *
1144 * @param[in] aResp Shared pointer for generating response message.
1145 * @param[in] policy power restore policy properties from request.
1146 *
1147 * @return None.
1148 */
1149static void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
1150 std::optional<std::string> policy)
1151{
1152 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1153
1154 const boost::container::flat_map<std::string, std::string> policyMaps = {
1155 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1156 "AlwaysOn"},
1157 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1158 "AlwaysOff"},
1159 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1160 "LastState"}};
1161
1162 std::string powerRestorPolicy;
1163
1164 auto policyMapsIt = policyMaps.find(*policy);
1165 if (policyMapsIt == policyMaps.end())
1166 {
1167 messages::internalError(aResp->res);
1168 return;
1169 }
1170
1171 powerRestorPolicy = policyMapsIt->second;
1172
1173 crow::connections::systemBus->async_method_call(
1174 [aResp](const boost::system::error_code ec) {
1175 if (ec)
1176 {
1177 messages::internalError(aResp->res);
1178 return;
1179 }
1180 },
1181 "xyz.openbmc_project.Settings",
1182 "/xyz/openbmc_project/control/host0/power_restore_policy",
1183 "org.freedesktop.DBus.Properties", "Set",
1184 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1185 std::variant<std::string>(powerRestorPolicy));
1186}
1187
AppaRao Pulia6349912019-10-18 17:16:08 +05301188#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1189/**
1190 * @brief Retrieves provisioning status
1191 *
1192 * @param[in] aResp Shared pointer for completing asynchronous calls.
1193 *
1194 * @return None.
1195 */
1196void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1197{
1198 BMCWEB_LOG_DEBUG << "Get OEM information.";
1199 crow::connections::systemBus->async_method_call(
1200 [aResp](const boost::system::error_code ec,
1201 const std::vector<std::pair<std::string, VariantType>>
1202 &propertiesList) {
1203 if (ec)
1204 {
1205 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1206 messages::internalError(aResp->res);
1207 return;
1208 }
1209
1210 const bool *provState = nullptr;
1211 const bool *lockState = nullptr;
1212 for (const std::pair<std::string, VariantType> &property :
1213 propertiesList)
1214 {
1215 if (property.first == "UfmProvisioned")
1216 {
1217 provState = std::get_if<bool>(&property.second);
1218 }
1219 else if (property.first == "UfmLocked")
1220 {
1221 lockState = std::get_if<bool>(&property.second);
1222 }
1223 }
1224
1225 if ((provState == nullptr) || (lockState == nullptr))
1226 {
1227 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1228 messages::internalError(aResp->res);
1229 return;
1230 }
1231
1232 nlohmann::json &oemPFR =
1233 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1234 if (*provState == true)
1235 {
1236 if (*lockState == true)
1237 {
1238 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1239 }
1240 else
1241 {
1242 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1243 }
1244 }
1245 else
1246 {
1247 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1248 }
1249 },
1250 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1251 "org.freedesktop.DBus.Properties", "GetAll",
1252 "xyz.openbmc_project.PFR.Attributes");
1253}
1254#endif
1255
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301256/**
Yong Li51709ff2019-09-30 14:13:04 +08001257 * @brief Translates watchdog timeout action DBUS property value to redfish.
1258 *
1259 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1260 *
1261 * @return Returns as a string, the timeout action in Redfish terms. If
1262 * translation cannot be done, returns an empty string.
1263 */
1264static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1265{
1266 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1267 {
1268 return "None";
1269 }
1270 else if (dbusAction ==
1271 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1272 {
1273 return "ResetSystem";
1274 }
1275 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1276 {
1277 return "PowerDown";
1278 }
1279 else if (dbusAction ==
1280 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1281 {
1282 return "PowerCycle";
1283 }
1284
1285 return "";
1286}
1287
1288/**
Yong Lic45f0082019-10-10 14:19:01 +08001289 *@brief Translates timeout action from Redfish to DBUS property value.
1290 *
1291 *@param[in] rfAction The timeout action in Redfish.
1292 *
1293 *@return Returns as a string, the time_out action as expected by DBUS.
1294 *If translation cannot be done, returns an empty string.
1295 */
1296
1297static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1298{
1299 if (rfAction == "None")
1300 {
1301 return "xyz.openbmc_project.State.Watchdog.Action.None";
1302 }
1303 else if (rfAction == "PowerCycle")
1304 {
1305 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1306 }
1307 else if (rfAction == "PowerDown")
1308 {
1309 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1310 }
1311 else if (rfAction == "ResetSystem")
1312 {
1313 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1314 }
1315
1316 return "";
1317}
1318
1319/**
Yong Li51709ff2019-09-30 14:13:04 +08001320 * @brief Retrieves host watchdog timer properties over DBUS
1321 *
1322 * @param[in] aResp Shared pointer for completing asynchronous calls.
1323 *
1324 * @return None.
1325 */
1326void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1327{
1328 BMCWEB_LOG_DEBUG << "Get host watchodg";
1329 crow::connections::systemBus->async_method_call(
1330 [aResp](const boost::system::error_code ec,
1331 PropertiesType &properties) {
1332 if (ec)
1333 {
1334 // watchdog service is stopped
1335 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1336 return;
1337 }
1338
1339 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1340
1341 nlohmann::json &hostWatchdogTimer =
1342 aResp->res.jsonValue["HostWatchdogTimer"];
1343
1344 // watchdog service is running/enabled
1345 hostWatchdogTimer["Status"]["State"] = "Enabled";
1346
1347 for (const auto &property : properties)
1348 {
1349 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1350 if (property.first == "Enabled")
1351 {
1352 const bool *state = std::get_if<bool>(&property.second);
1353
1354 if (!state)
1355 {
1356 messages::internalError(aResp->res);
1357 continue;
1358 }
1359
1360 hostWatchdogTimer["FunctionEnabled"] = *state;
1361 }
1362 else if (property.first == "ExpireAction")
1363 {
1364 const std::string *s =
1365 std::get_if<std::string>(&property.second);
1366 if (!s)
1367 {
1368 messages::internalError(aResp->res);
1369 continue;
1370 }
1371
1372 std::string action = dbusToRfWatchdogAction(*s);
1373 if (action.empty())
1374 {
1375 messages::internalError(aResp->res);
1376 continue;
1377 }
1378 hostWatchdogTimer["TimeoutAction"] = action;
1379 }
1380 }
1381 },
1382 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1383 "org.freedesktop.DBus.Properties", "GetAll",
1384 "xyz.openbmc_project.State.Watchdog");
1385}
1386
1387/**
Yong Lic45f0082019-10-10 14:19:01 +08001388 * @brief Sets Host WatchDog Timer properties.
1389 *
1390 * @param[in] aResp Shared pointer for generating response message.
1391 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1392 * RF request.
1393 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1394 *
1395 * @return None.
1396 */
1397static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1398 const std::optional<bool> wdtEnable,
1399 const std::optional<std::string> &wdtTimeOutAction)
1400{
1401 BMCWEB_LOG_DEBUG << "Set host watchdog";
1402
1403 if (wdtTimeOutAction)
1404 {
1405 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1406 // check if TimeOut Action is Valid
1407 if (wdtTimeOutActStr.empty())
1408 {
1409 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1410 << *wdtTimeOutAction;
1411 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1412 "TimeoutAction");
1413 return;
1414 }
1415
1416 crow::connections::systemBus->async_method_call(
1417 [aResp](const boost::system::error_code ec) {
1418 if (ec)
1419 {
1420 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1421 messages::internalError(aResp->res);
1422 return;
1423 }
1424 },
1425 "xyz.openbmc_project.Watchdog",
1426 "/xyz/openbmc_project/watchdog/host0",
1427 "org.freedesktop.DBus.Properties", "Set",
1428 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1429 std::variant<std::string>(wdtTimeOutActStr));
1430 }
1431
1432 if (wdtEnable)
1433 {
1434 crow::connections::systemBus->async_method_call(
1435 [aResp](const boost::system::error_code ec) {
1436 if (ec)
1437 {
1438 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1439 messages::internalError(aResp->res);
1440 return;
1441 }
1442 },
1443 "xyz.openbmc_project.Watchdog",
1444 "/xyz/openbmc_project/watchdog/host0",
1445 "org.freedesktop.DBus.Properties", "Set",
1446 "xyz.openbmc_project.State.Watchdog", "Enabled",
1447 std::variant<bool>(*wdtEnable));
1448 }
1449}
1450
1451/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001452 * SystemsCollection derived class for delivering ComputerSystems Collection
1453 * Schema
1454 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001455class SystemsCollection : public Node
1456{
1457 public:
1458 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1459 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001460 entityPrivileges = {
1461 {boost::beast::http::verb::get, {{"Login"}}},
1462 {boost::beast::http::verb::head, {{"Login"}}},
1463 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1464 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1465 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1466 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1467 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001468
Ed Tanous1abe55e2018-09-05 08:30:59 -07001469 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001470 void doGet(crow::Response &res, const crow::Request &req,
1471 const std::vector<std::string> &params) override
1472 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001473 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001474 res.jsonValue["@odata.type"] =
1475 "#ComputerSystemCollection.ComputerSystemCollection";
1476 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001477 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001478
1479 crow::connections::systemBus->async_method_call(
1480 [asyncResp](const boost::system::error_code ec,
1481 const std::variant<std::string> &hostName) {
1482 nlohmann::json &iface_array =
1483 asyncResp->res.jsonValue["Members"];
1484 iface_array = nlohmann::json::array();
1485 auto &count = asyncResp->res.jsonValue["Members@odata.count"];
1486 count = 0;
1487 if (ec)
1488 {
1489 iface_array.push_back(
1490 {{"@odata.id", "/redfish/v1/Systems/system"}});
1491 count = iface_array.size();
1492 return;
1493 }
1494 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1495 iface_array.push_back(
1496 {{"@odata.id", "/redfish/v1/Systems/system"}});
1497 iface_array.push_back(
1498 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1499 count = iface_array.size();
1500 },
1501 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/vmi",
1502 "org.freedesktop.DBus.Properties", "Get",
1503 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001504 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001505};
1506
1507/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001508 * SystemActionsReset class supports handle POST method for Reset action.
1509 * The class retrieves and sends data directly to D-Bus.
1510 */
1511class SystemActionsReset : public Node
1512{
1513 public:
1514 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001515 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001516 {
1517 entityPrivileges = {
1518 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1519 }
1520
1521 private:
1522 /**
1523 * Function handles POST method request.
1524 * Analyzes POST body message before sends Reset request data to D-Bus.
1525 */
1526 void doPost(crow::Response &res, const crow::Request &req,
1527 const std::vector<std::string> &params) override
1528 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001529 auto asyncResp = std::make_shared<AsyncResp>(res);
1530
1531 std::string resetType;
1532 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001533 {
1534 return;
1535 }
1536
Jason M. Billsd22c8392019-06-03 13:59:03 -07001537 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001538 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001539 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001540 if (resetType == "On")
1541 {
1542 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001543 hostCommand = true;
1544 }
1545 else if (resetType == "ForceOff")
1546 {
1547 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1548 hostCommand = false;
1549 }
1550 else if (resetType == "ForceOn")
1551 {
1552 command = "xyz.openbmc_project.State.Host.Transition.On";
1553 hostCommand = true;
1554 }
1555 else if (resetType == "ForceRestart")
1556 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001557 command =
1558 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1559 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001560 }
1561 else if (resetType == "GracefulShutdown")
1562 {
1563 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001564 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001565 }
1566 else if (resetType == "GracefulRestart")
1567 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001568 command =
1569 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001570 hostCommand = true;
1571 }
1572 else if (resetType == "PowerCycle")
1573 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001574 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1575 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001576 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001577 else if (resetType == "Nmi")
1578 {
1579 doNMI(asyncResp);
1580 return;
1581 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001582 else
1583 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001584 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001585 return;
1586 }
1587
Jason M. Billsd22c8392019-06-03 13:59:03 -07001588 if (hostCommand)
1589 {
1590 crow::connections::systemBus->async_method_call(
1591 [asyncResp, resetType](const boost::system::error_code ec) {
1592 if (ec)
1593 {
1594 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1595 if (ec.value() == boost::asio::error::invalid_argument)
1596 {
1597 messages::actionParameterNotSupported(
1598 asyncResp->res, resetType, "Reset");
1599 }
1600 else
1601 {
1602 messages::internalError(asyncResp->res);
1603 }
1604 return;
1605 }
1606 messages::success(asyncResp->res);
1607 },
1608 "xyz.openbmc_project.State.Host",
1609 "/xyz/openbmc_project/state/host0",
1610 "org.freedesktop.DBus.Properties", "Set",
1611 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1612 std::variant<std::string>{command});
1613 }
1614 else
1615 {
1616 crow::connections::systemBus->async_method_call(
1617 [asyncResp, resetType](const boost::system::error_code ec) {
1618 if (ec)
1619 {
1620 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1621 if (ec.value() == boost::asio::error::invalid_argument)
1622 {
1623 messages::actionParameterNotSupported(
1624 asyncResp->res, resetType, "Reset");
1625 }
1626 else
1627 {
1628 messages::internalError(asyncResp->res);
1629 }
1630 return;
1631 }
1632 messages::success(asyncResp->res);
1633 },
1634 "xyz.openbmc_project.State.Chassis",
1635 "/xyz/openbmc_project/state/chassis0",
1636 "org.freedesktop.DBus.Properties", "Set",
1637 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1638 std::variant<std::string>{command});
1639 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001640 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001641 /**
1642 * Function transceives data with dbus directly.
1643 */
1644 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1645 {
1646 constexpr char const *serviceName =
1647 "xyz.openbmc_project.Control.Host.NMI";
1648 constexpr char const *objectPath =
1649 "/xyz/openbmc_project/control/host0/nmi";
1650 constexpr char const *interfaceName =
1651 "xyz.openbmc_project.Control.Host.NMI";
1652 constexpr char const *method = "NMI";
1653
1654 crow::connections::systemBus->async_method_call(
1655 [asyncResp](const boost::system::error_code ec) {
1656 if (ec)
1657 {
1658 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1659 messages::internalError(asyncResp->res);
1660 return;
1661 }
1662 messages::success(asyncResp->res);
1663 },
1664 serviceName, objectPath, interfaceName, method);
1665 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001666};
1667
1668/**
Ed Tanous66173382018-08-15 18:20:59 -07001669 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001670 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001671class Systems : public Node
1672{
1673 public:
1674 /*
1675 * Default Constructor
1676 */
Ed Tanous029573d2019-02-01 10:57:49 -08001677 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001678 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001679 entityPrivileges = {
1680 {boost::beast::http::verb::get, {{"Login"}}},
1681 {boost::beast::http::verb::head, {{"Login"}}},
1682 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1683 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1684 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1685 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001686 }
1687
Ed Tanous1abe55e2018-09-05 08:30:59 -07001688 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001689 /**
1690 * Functions triggers appropriate requests on DBus
1691 */
1692 void doGet(crow::Response &res, const crow::Request &req,
1693 const std::vector<std::string> &params) override
1694 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301695 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001696 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001697 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001698 res.jsonValue["SystemType"] = "Physical";
1699 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001700 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1701 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001702 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001703 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001704 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001705
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001706 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001707 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001708 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001709 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001710 res.jsonValue["Storage"] = {
1711 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001712
Ed Tanouscc340dd2018-08-29 13:43:38 -07001713 // TODO Need to support ForceRestart.
1714 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1715 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001716 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001717 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001718 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001719 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001720
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001721 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001722 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001723
Carol Wangd82a3ac2019-11-21 13:56:38 +08001724 res.jsonValue["Bios"] = {
1725 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1726
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001727 res.jsonValue["Links"]["ManagedBy"] = {
1728 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1729
1730 res.jsonValue["Status"] = {
1731 {"Health", "OK"},
1732 {"State", "Enabled"},
1733 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001734 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001735
James Feiste284a7c2019-11-20 16:20:23 -08001736 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001737 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001738 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001739 "xyz.openbmc_project.Inventory.Item.Drive",
1740 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001741
1742 auto health = std::make_shared<HealthPopulate>(asyncResp);
1743 crow::connections::systemBus->async_method_call(
1744 [health](const boost::system::error_code ec,
1745 std::vector<std::string> &resp) {
1746 if (ec)
1747 {
1748 // no inventory
1749 return;
1750 }
1751
1752 health->inventory = std::move(resp);
1753 },
1754 "xyz.openbmc_project.ObjectMapper",
1755 "/xyz/openbmc_project/object_mapper",
1756 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1757 int32_t(0), inventoryForSystems);
1758
1759 health->populate();
1760
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001761 getMainChassisId(asyncResp, [](const std::string &chassisId,
1762 std::shared_ptr<AsyncResp> aRsp) {
1763 aRsp->res.jsonValue["Links"]["Chassis"] = {
1764 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1765 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301766
1767 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001768 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001769 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301770 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001771 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001772 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001773 getPowerRestorePolicy(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301774#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1775 getProvisioningStatus(asyncResp);
1776#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001777 }
1778
Ed Tanous1abe55e2018-09-05 08:30:59 -07001779 void doPatch(crow::Response &res, const crow::Request &req,
1780 const std::vector<std::string> &params) override
1781 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301782 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301783 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001784 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001785 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001786 auto asyncResp = std::make_shared<AsyncResp>(res);
1787
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001788 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001789 bootProps, "WatchdogTimer", wdtTimerProps,
1790 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001791 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001792 return;
1793 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301794
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001795 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001796
1797 if (wdtTimerProps)
1798 {
1799 std::optional<bool> wdtEnable;
1800 std::optional<std::string> wdtTimeOutAction;
1801
1802 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1803 "FunctionEnabled", wdtEnable,
1804 "TimeoutAction", wdtTimeOutAction))
1805 {
1806 return;
1807 }
1808 setWDTProperties(asyncResp, std::move(wdtEnable),
1809 std::move(wdtTimeOutAction));
1810 }
1811
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301812 if (bootProps)
1813 {
1814 std::optional<std::string> bootSource;
1815 std::optional<std::string> bootEnable;
1816
1817 if (!json_util::readJson(*bootProps, asyncResp->res,
1818 "BootSourceOverrideTarget", bootSource,
1819 "BootSourceOverrideEnabled", bootEnable))
1820 {
1821 return;
1822 }
1823 setBootProperties(asyncResp, std::move(bootSource),
1824 std::move(bootEnable));
1825 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001826
Ed Tanous9712f8a2018-09-21 13:38:49 -07001827 if (indicatorLed)
1828 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301829 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001830 }
George Liuc6a620f2020-04-10 17:18:11 +08001831
1832 if (powerRestorePolicy)
1833 {
1834 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
1835 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001836 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001837};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001838} // namespace redfish