blob: 1fc4b4fe13f81a097b28e8504b2d0f5cf184715c [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."
Gunnar Mills8c888602020-05-01 14:25:09 -0500619 "Quiesced")
620 {
621 aResp->res.jsonValue["PowerState"] = "On";
622 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
623 }
624 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600625 "DiagnosticMode")
626 {
627 aResp->res.jsonValue["PowerState"] = "On";
628 aResp->res.jsonValue["Status"]["State"] = "InTest";
629 }
Ed Tanous66173382018-08-15 18:20:59 -0700630 else
631 {
632 aResp->res.jsonValue["PowerState"] = "Off";
633 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700634 }
635 }
636 },
637 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700638 "org.freedesktop.DBus.Properties", "Get",
639 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700640}
641
642/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530643 * @brief Traslates boot source DBUS property value to redfish.
644 *
645 * @param[in] dbusSource The boot source in DBUS speak.
646 *
647 * @return Returns as a string, the boot source in Redfish terms. If translation
648 * cannot be done, returns an empty string.
649 */
650static std::string dbusToRfBootSource(const std::string &dbusSource)
651{
652 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
653 {
654 return "None";
655 }
656 else if (dbusSource ==
657 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
658 {
659 return "Hdd";
660 }
661 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530662 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530663 {
664 return "Cd";
665 }
666 else if (dbusSource ==
667 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
668 {
669 return "Pxe";
670 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700671 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700672 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700673 {
674 return "Usb";
675 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530676 else
677 {
678 return "";
679 }
680}
681
682/**
683 * @brief Traslates boot mode DBUS property value to redfish.
684 *
685 * @param[in] dbusMode The boot mode in DBUS speak.
686 *
687 * @return Returns as a string, the boot mode in Redfish terms. If translation
688 * cannot be done, returns an empty string.
689 */
690static std::string dbusToRfBootMode(const std::string &dbusMode)
691{
692 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
693 {
694 return "None";
695 }
696 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
697 {
698 return "Diags";
699 }
700 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
701 {
702 return "BiosSetup";
703 }
704 else
705 {
706 return "";
707 }
708}
709
710/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700711 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712 *
713 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700714 * @param[out] bootSource The DBus source
715 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530716 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700717 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530718 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700719static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
720 const std::string &rfSource,
721 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530722{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700723 // The caller has initialized the bootSource and bootMode to:
724 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
725 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
726 // Only modify the bootSource/bootMode variable needed to achieve the
727 // desired boot action.
728
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530729 if (rfSource == "None")
730 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700731 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530732 }
733 else if (rfSource == "Pxe")
734 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700735 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
736 }
737 else if (rfSource == "Hdd")
738 {
739 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
740 }
741 else if (rfSource == "Diags")
742 {
743 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
744 }
745 else if (rfSource == "Cd")
746 {
747 bootSource =
748 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
749 }
750 else if (rfSource == "BiosSetup")
751 {
752 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530753 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700754 else if (rfSource == "Usb")
755 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700756 bootSource =
757 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700758 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530759 else
760 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700761 BMCWEB_LOG_DEBUG << "Invalid property value for "
762 "BootSourceOverrideTarget: "
763 << bootSource;
764 messages::propertyValueNotInList(aResp->res, rfSource,
765 "BootSourceTargetOverride");
766 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530767 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700768 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530769}
770
771/**
772 * @brief Retrieves boot mode over DBUS and fills out the response
773 *
774 * @param[in] aResp Shared pointer for generating response message.
775 * @param[in] bootDbusObj The dbus object to query for boot properties.
776 *
777 * @return None.
778 */
779static void getBootMode(std::shared_ptr<AsyncResp> aResp,
780 std::string bootDbusObj)
781{
782 crow::connections::systemBus->async_method_call(
783 [aResp](const boost::system::error_code ec,
784 const std::variant<std::string> &bootMode) {
785 if (ec)
786 {
787 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
788 messages::internalError(aResp->res);
789 return;
790 }
791
792 const std::string *bootModeStr =
793 std::get_if<std::string>(&bootMode);
794
795 if (!bootModeStr)
796 {
797 messages::internalError(aResp->res);
798 return;
799 }
800
801 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
802
803 // TODO (Santosh): Do we need to support override mode?
804 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
805 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
806 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700807 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530808
809 if (*bootModeStr !=
810 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
811 {
812 auto rfMode = dbusToRfBootMode(*bootModeStr);
813 if (!rfMode.empty())
814 {
815 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
816 rfMode;
817 }
818 }
819
820 // If the BootSourceOverrideTarget is still "None" at the end,
821 // reset the BootSourceOverrideEnabled to indicate that
822 // overrides are disabled
823 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
824 "None")
825 {
826 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
827 "Disabled";
828 }
829 },
830 "xyz.openbmc_project.Settings", bootDbusObj,
831 "org.freedesktop.DBus.Properties", "Get",
832 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
833}
834
835/**
836 * @brief Retrieves boot source over DBUS
837 *
838 * @param[in] aResp Shared pointer for generating response message.
839 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
840 *
841 * @return None.
842 */
843static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
844{
845 std::string bootDbusObj =
846 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
847 : "/xyz/openbmc_project/control/host0/boot";
848
849 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
850 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
851 (oneTimeEnabled) ? "Once" : "Continuous";
852
853 crow::connections::systemBus->async_method_call(
854 [aResp, bootDbusObj](const boost::system::error_code ec,
855 const std::variant<std::string> &bootSource) {
856 if (ec)
857 {
858 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
859 messages::internalError(aResp->res);
860 return;
861 }
862
863 const std::string *bootSourceStr =
864 std::get_if<std::string>(&bootSource);
865
866 if (!bootSourceStr)
867 {
868 messages::internalError(aResp->res);
869 return;
870 }
871 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
872
873 auto rfSource = dbusToRfBootSource(*bootSourceStr);
874 if (!rfSource.empty())
875 {
876 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
877 rfSource;
878 }
879 },
880 "xyz.openbmc_project.Settings", bootDbusObj,
881 "org.freedesktop.DBus.Properties", "Get",
882 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
883 getBootMode(std::move(aResp), std::move(bootDbusObj));
884}
885
886/**
887 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
888 * get boot source and boot mode.
889 *
890 * @param[in] aResp Shared pointer for generating response message.
891 *
892 * @return None.
893 */
894static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
895{
896 BMCWEB_LOG_DEBUG << "Get boot information.";
897
898 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800899 [aResp](const boost::system::error_code ec,
900 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530901 if (ec)
902 {
903 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700904 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530905 return;
906 }
907
908 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
909
910 if (!oneTimePtr)
911 {
912 messages::internalError(aResp->res);
913 return;
914 }
915 getBootSource(aResp, *oneTimePtr);
916 },
917 "xyz.openbmc_project.Settings",
918 "/xyz/openbmc_project/control/host0/boot/one_time",
919 "org.freedesktop.DBus.Properties", "Get",
920 "xyz.openbmc_project.Object.Enable", "Enabled");
921}
922
923/**
George Liuc6a620f2020-04-10 17:18:11 +0800924 * @brief Retrieves power restore policy over DBUS.
925 *
926 * @param[in] aResp Shared pointer for generating response message.
927 *
928 * @return None.
929 */
930void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
931{
932 BMCWEB_LOG_DEBUG << "Get power restore policy";
933
934 crow::connections::systemBus->async_method_call(
935 [aResp](const boost::system::error_code ec,
936 sdbusplus::message::variant<std::string> &policy) {
937 if (ec)
938 {
939 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
940 return;
941 }
942
943 const boost::container::flat_map<std::string, std::string>
944 policyMaps = {
945 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
946 "AlwaysOn",
947 "AlwaysOn"},
948 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
949 "AlwaysOff",
950 "AlwaysOff"},
951 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
952 "LastState",
953 "LastState"}};
954
955 const std::string *policyPtr = std::get_if<std::string>(&policy);
956
957 if (!policyPtr)
958 {
959 messages::internalError(aResp->res);
960 return;
961 }
962
963 auto policyMapsIt = policyMaps.find(*policyPtr);
964 if (policyMapsIt == policyMaps.end())
965 {
966 messages::internalError(aResp->res);
967 return;
968 }
969
970 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
971 },
972 "xyz.openbmc_project.Settings",
973 "/xyz/openbmc_project/control/host0/power_restore_policy",
974 "org.freedesktop.DBus.Properties", "Get",
975 "xyz.openbmc_project.Control.Power.RestorePolicy",
976 "PowerRestorePolicy");
977}
978
979/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530980 * @brief Sets boot properties into DBUS object(s).
981 *
982 * @param[in] aResp Shared pointer for generating response message.
983 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
984 * @param[in] bootSource The boot source to set.
985 * @param[in] bootEnable The source override "enable" to set.
986 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700987 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530988 */
989static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
990 bool oneTimeEnabled,
991 std::optional<std::string> bootSource,
992 std::optional<std::string> bootEnable)
993{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700994 std::string bootSourceStr =
995 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
996 std::string bootModeStr =
997 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530998 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700999 bool useBootSource = true;
1000
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301001 // Validate incoming parameters
1002 if (bootEnable)
1003 {
1004 if (*bootEnable == "Once")
1005 {
1006 oneTimeSetting = true;
1007 }
1008 else if (*bootEnable == "Continuous")
1009 {
1010 oneTimeSetting = false;
1011 }
1012 else if (*bootEnable == "Disabled")
1013 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001014 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301015 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001016 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301017 }
1018 else
1019 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301020 BMCWEB_LOG_DEBUG << "Unsupported value for "
1021 "BootSourceOverrideEnabled: "
1022 << *bootEnable;
1023 messages::propertyValueNotInList(aResp->res, *bootEnable,
1024 "BootSourceOverrideEnabled");
1025 return;
1026 }
1027 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301028
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001029 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 {
1031 // Source target specified
1032 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1033 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001034 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1035 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301036 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001037 BMCWEB_LOG_DEBUG
1038 << "Invalid property value for BootSourceOverrideTarget: "
1039 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301040 messages::propertyValueNotInList(aResp->res, *bootSource,
1041 "BootSourceTargetOverride");
1042 return;
1043 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001044 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301045
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001046 // Act on validated parameters
1047 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1048 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1049 const char *bootObj =
1050 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1051 : "/xyz/openbmc_project/control/host0/boot";
1052
1053 crow::connections::systemBus->async_method_call(
1054 [aResp](const boost::system::error_code ec) {
1055 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301056 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001057 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1058 messages::internalError(aResp->res);
1059 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301060 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001061 BMCWEB_LOG_DEBUG << "Boot source update done.";
1062 },
1063 "xyz.openbmc_project.Settings", bootObj,
1064 "org.freedesktop.DBus.Properties", "Set",
1065 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1066 std::variant<std::string>(bootSourceStr));
1067
1068 crow::connections::systemBus->async_method_call(
1069 [aResp](const boost::system::error_code ec) {
1070 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301071 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001072 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1073 messages::internalError(aResp->res);
1074 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301075 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001076 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1077 },
1078 "xyz.openbmc_project.Settings", bootObj,
1079 "org.freedesktop.DBus.Properties", "Set",
1080 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1081 std::variant<std::string>(bootModeStr));
1082
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301083 crow::connections::systemBus->async_method_call(
1084 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1085 if (ec)
1086 {
1087 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1088 messages::internalError(aResp->res);
1089 return;
1090 }
1091 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1092 },
1093 "xyz.openbmc_project.Settings",
1094 "/xyz/openbmc_project/control/host0/boot/one_time",
1095 "org.freedesktop.DBus.Properties", "Set",
1096 "xyz.openbmc_project.Object.Enable", "Enabled",
1097 std::variant<bool>(oneTimeSetting));
1098}
1099
1100/**
1101 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1102 * set boot source/boot mode properties.
1103 *
1104 * @param[in] aResp Shared pointer for generating response message.
1105 * @param[in] bootSource The boot source from incoming RF request.
1106 * @param[in] bootEnable The boot override enable from incoming RF request.
1107 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001108 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301109 */
1110static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1111 std::optional<std::string> bootSource,
1112 std::optional<std::string> bootEnable)
1113{
1114 BMCWEB_LOG_DEBUG << "Set boot information.";
1115
1116 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001117 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301118 bootEnable{std::move(bootEnable)}](
1119 const boost::system::error_code ec,
1120 const sdbusplus::message::variant<bool> &oneTime) {
1121 if (ec)
1122 {
1123 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1124 messages::internalError(aResp->res);
1125 return;
1126 }
1127
1128 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1129
1130 if (!oneTimePtr)
1131 {
1132 messages::internalError(aResp->res);
1133 return;
1134 }
1135
1136 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1137
1138 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1139 std::move(bootEnable));
1140 },
1141 "xyz.openbmc_project.Settings",
1142 "/xyz/openbmc_project/control/host0/boot/one_time",
1143 "org.freedesktop.DBus.Properties", "Get",
1144 "xyz.openbmc_project.Object.Enable", "Enabled");
1145}
1146
George Liuc6a620f2020-04-10 17:18:11 +08001147/**
1148 * @brief Sets power restore policy properties.
1149 *
1150 * @param[in] aResp Shared pointer for generating response message.
1151 * @param[in] policy power restore policy properties from request.
1152 *
1153 * @return None.
1154 */
1155static void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
1156 std::optional<std::string> policy)
1157{
1158 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1159
1160 const boost::container::flat_map<std::string, std::string> policyMaps = {
1161 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1162 "AlwaysOn"},
1163 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1164 "AlwaysOff"},
1165 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1166 "LastState"}};
1167
1168 std::string powerRestorPolicy;
1169
1170 auto policyMapsIt = policyMaps.find(*policy);
1171 if (policyMapsIt == policyMaps.end())
1172 {
1173 messages::internalError(aResp->res);
1174 return;
1175 }
1176
1177 powerRestorPolicy = policyMapsIt->second;
1178
1179 crow::connections::systemBus->async_method_call(
1180 [aResp](const boost::system::error_code ec) {
1181 if (ec)
1182 {
1183 messages::internalError(aResp->res);
1184 return;
1185 }
1186 },
1187 "xyz.openbmc_project.Settings",
1188 "/xyz/openbmc_project/control/host0/power_restore_policy",
1189 "org.freedesktop.DBus.Properties", "Set",
1190 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1191 std::variant<std::string>(powerRestorPolicy));
1192}
1193
AppaRao Pulia6349912019-10-18 17:16:08 +05301194#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1195/**
1196 * @brief Retrieves provisioning status
1197 *
1198 * @param[in] aResp Shared pointer for completing asynchronous calls.
1199 *
1200 * @return None.
1201 */
1202void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1203{
1204 BMCWEB_LOG_DEBUG << "Get OEM information.";
1205 crow::connections::systemBus->async_method_call(
1206 [aResp](const boost::system::error_code ec,
1207 const std::vector<std::pair<std::string, VariantType>>
1208 &propertiesList) {
1209 if (ec)
1210 {
1211 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1212 messages::internalError(aResp->res);
1213 return;
1214 }
1215
1216 const bool *provState = nullptr;
1217 const bool *lockState = nullptr;
1218 for (const std::pair<std::string, VariantType> &property :
1219 propertiesList)
1220 {
1221 if (property.first == "UfmProvisioned")
1222 {
1223 provState = std::get_if<bool>(&property.second);
1224 }
1225 else if (property.first == "UfmLocked")
1226 {
1227 lockState = std::get_if<bool>(&property.second);
1228 }
1229 }
1230
1231 if ((provState == nullptr) || (lockState == nullptr))
1232 {
1233 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1234 messages::internalError(aResp->res);
1235 return;
1236 }
1237
1238 nlohmann::json &oemPFR =
1239 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1240 if (*provState == true)
1241 {
1242 if (*lockState == true)
1243 {
1244 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1245 }
1246 else
1247 {
1248 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1249 }
1250 }
1251 else
1252 {
1253 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1254 }
1255 },
1256 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1257 "org.freedesktop.DBus.Properties", "GetAll",
1258 "xyz.openbmc_project.PFR.Attributes");
1259}
1260#endif
1261
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301262/**
Yong Li51709ff2019-09-30 14:13:04 +08001263 * @brief Translates watchdog timeout action DBUS property value to redfish.
1264 *
1265 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1266 *
1267 * @return Returns as a string, the timeout action in Redfish terms. If
1268 * translation cannot be done, returns an empty string.
1269 */
1270static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1271{
1272 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1273 {
1274 return "None";
1275 }
1276 else if (dbusAction ==
1277 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1278 {
1279 return "ResetSystem";
1280 }
1281 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1282 {
1283 return "PowerDown";
1284 }
1285 else if (dbusAction ==
1286 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1287 {
1288 return "PowerCycle";
1289 }
1290
1291 return "";
1292}
1293
1294/**
Yong Lic45f0082019-10-10 14:19:01 +08001295 *@brief Translates timeout action from Redfish to DBUS property value.
1296 *
1297 *@param[in] rfAction The timeout action in Redfish.
1298 *
1299 *@return Returns as a string, the time_out action as expected by DBUS.
1300 *If translation cannot be done, returns an empty string.
1301 */
1302
1303static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1304{
1305 if (rfAction == "None")
1306 {
1307 return "xyz.openbmc_project.State.Watchdog.Action.None";
1308 }
1309 else if (rfAction == "PowerCycle")
1310 {
1311 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1312 }
1313 else if (rfAction == "PowerDown")
1314 {
1315 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1316 }
1317 else if (rfAction == "ResetSystem")
1318 {
1319 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1320 }
1321
1322 return "";
1323}
1324
1325/**
Yong Li51709ff2019-09-30 14:13:04 +08001326 * @brief Retrieves host watchdog timer properties over DBUS
1327 *
1328 * @param[in] aResp Shared pointer for completing asynchronous calls.
1329 *
1330 * @return None.
1331 */
1332void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1333{
1334 BMCWEB_LOG_DEBUG << "Get host watchodg";
1335 crow::connections::systemBus->async_method_call(
1336 [aResp](const boost::system::error_code ec,
1337 PropertiesType &properties) {
1338 if (ec)
1339 {
1340 // watchdog service is stopped
1341 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1342 return;
1343 }
1344
1345 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1346
1347 nlohmann::json &hostWatchdogTimer =
1348 aResp->res.jsonValue["HostWatchdogTimer"];
1349
1350 // watchdog service is running/enabled
1351 hostWatchdogTimer["Status"]["State"] = "Enabled";
1352
1353 for (const auto &property : properties)
1354 {
1355 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1356 if (property.first == "Enabled")
1357 {
1358 const bool *state = std::get_if<bool>(&property.second);
1359
1360 if (!state)
1361 {
1362 messages::internalError(aResp->res);
1363 continue;
1364 }
1365
1366 hostWatchdogTimer["FunctionEnabled"] = *state;
1367 }
1368 else if (property.first == "ExpireAction")
1369 {
1370 const std::string *s =
1371 std::get_if<std::string>(&property.second);
1372 if (!s)
1373 {
1374 messages::internalError(aResp->res);
1375 continue;
1376 }
1377
1378 std::string action = dbusToRfWatchdogAction(*s);
1379 if (action.empty())
1380 {
1381 messages::internalError(aResp->res);
1382 continue;
1383 }
1384 hostWatchdogTimer["TimeoutAction"] = action;
1385 }
1386 }
1387 },
1388 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1389 "org.freedesktop.DBus.Properties", "GetAll",
1390 "xyz.openbmc_project.State.Watchdog");
1391}
1392
1393/**
Yong Lic45f0082019-10-10 14:19:01 +08001394 * @brief Sets Host WatchDog Timer properties.
1395 *
1396 * @param[in] aResp Shared pointer for generating response message.
1397 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1398 * RF request.
1399 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1400 *
1401 * @return None.
1402 */
1403static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1404 const std::optional<bool> wdtEnable,
1405 const std::optional<std::string> &wdtTimeOutAction)
1406{
1407 BMCWEB_LOG_DEBUG << "Set host watchdog";
1408
1409 if (wdtTimeOutAction)
1410 {
1411 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1412 // check if TimeOut Action is Valid
1413 if (wdtTimeOutActStr.empty())
1414 {
1415 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1416 << *wdtTimeOutAction;
1417 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1418 "TimeoutAction");
1419 return;
1420 }
1421
1422 crow::connections::systemBus->async_method_call(
1423 [aResp](const boost::system::error_code ec) {
1424 if (ec)
1425 {
1426 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1427 messages::internalError(aResp->res);
1428 return;
1429 }
1430 },
1431 "xyz.openbmc_project.Watchdog",
1432 "/xyz/openbmc_project/watchdog/host0",
1433 "org.freedesktop.DBus.Properties", "Set",
1434 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1435 std::variant<std::string>(wdtTimeOutActStr));
1436 }
1437
1438 if (wdtEnable)
1439 {
1440 crow::connections::systemBus->async_method_call(
1441 [aResp](const boost::system::error_code ec) {
1442 if (ec)
1443 {
1444 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1445 messages::internalError(aResp->res);
1446 return;
1447 }
1448 },
1449 "xyz.openbmc_project.Watchdog",
1450 "/xyz/openbmc_project/watchdog/host0",
1451 "org.freedesktop.DBus.Properties", "Set",
1452 "xyz.openbmc_project.State.Watchdog", "Enabled",
1453 std::variant<bool>(*wdtEnable));
1454 }
1455}
1456
1457/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001458 * SystemsCollection derived class for delivering ComputerSystems Collection
1459 * Schema
1460 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001461class SystemsCollection : public Node
1462{
1463 public:
1464 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1465 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001466 entityPrivileges = {
1467 {boost::beast::http::verb::get, {{"Login"}}},
1468 {boost::beast::http::verb::head, {{"Login"}}},
1469 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1470 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1471 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1472 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1473 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001474
Ed Tanous1abe55e2018-09-05 08:30:59 -07001475 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001476 void doGet(crow::Response &res, const crow::Request &req,
1477 const std::vector<std::string> &params) override
1478 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001479 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001480 res.jsonValue["@odata.type"] =
1481 "#ComputerSystemCollection.ComputerSystemCollection";
1482 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001483 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001484
1485 crow::connections::systemBus->async_method_call(
1486 [asyncResp](const boost::system::error_code ec,
1487 const std::variant<std::string> &hostName) {
1488 nlohmann::json &iface_array =
1489 asyncResp->res.jsonValue["Members"];
1490 iface_array = nlohmann::json::array();
1491 auto &count = asyncResp->res.jsonValue["Members@odata.count"];
1492 count = 0;
1493 if (ec)
1494 {
1495 iface_array.push_back(
1496 {{"@odata.id", "/redfish/v1/Systems/system"}});
1497 count = iface_array.size();
1498 return;
1499 }
1500 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1501 iface_array.push_back(
1502 {{"@odata.id", "/redfish/v1/Systems/system"}});
1503 iface_array.push_back(
1504 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1505 count = iface_array.size();
1506 },
1507 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/vmi",
1508 "org.freedesktop.DBus.Properties", "Get",
1509 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001510 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001511};
1512
1513/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001514 * SystemActionsReset class supports handle POST method for Reset action.
1515 * The class retrieves and sends data directly to D-Bus.
1516 */
1517class SystemActionsReset : public Node
1518{
1519 public:
1520 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001521 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001522 {
1523 entityPrivileges = {
1524 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1525 }
1526
1527 private:
1528 /**
1529 * Function handles POST method request.
1530 * Analyzes POST body message before sends Reset request data to D-Bus.
1531 */
1532 void doPost(crow::Response &res, const crow::Request &req,
1533 const std::vector<std::string> &params) override
1534 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001535 auto asyncResp = std::make_shared<AsyncResp>(res);
1536
1537 std::string resetType;
1538 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001539 {
1540 return;
1541 }
1542
Jason M. Billsd22c8392019-06-03 13:59:03 -07001543 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001544 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001545 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001546 if (resetType == "On")
1547 {
1548 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001549 hostCommand = true;
1550 }
1551 else if (resetType == "ForceOff")
1552 {
1553 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1554 hostCommand = false;
1555 }
1556 else if (resetType == "ForceOn")
1557 {
1558 command = "xyz.openbmc_project.State.Host.Transition.On";
1559 hostCommand = true;
1560 }
1561 else if (resetType == "ForceRestart")
1562 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001563 command =
1564 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1565 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001566 }
1567 else if (resetType == "GracefulShutdown")
1568 {
1569 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001570 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001571 }
1572 else if (resetType == "GracefulRestart")
1573 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001574 command =
1575 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001576 hostCommand = true;
1577 }
1578 else if (resetType == "PowerCycle")
1579 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001580 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1581 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001582 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001583 else if (resetType == "Nmi")
1584 {
1585 doNMI(asyncResp);
1586 return;
1587 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001588 else
1589 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001590 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001591 return;
1592 }
1593
Jason M. Billsd22c8392019-06-03 13:59:03 -07001594 if (hostCommand)
1595 {
1596 crow::connections::systemBus->async_method_call(
1597 [asyncResp, resetType](const boost::system::error_code ec) {
1598 if (ec)
1599 {
1600 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1601 if (ec.value() == boost::asio::error::invalid_argument)
1602 {
1603 messages::actionParameterNotSupported(
1604 asyncResp->res, resetType, "Reset");
1605 }
1606 else
1607 {
1608 messages::internalError(asyncResp->res);
1609 }
1610 return;
1611 }
1612 messages::success(asyncResp->res);
1613 },
1614 "xyz.openbmc_project.State.Host",
1615 "/xyz/openbmc_project/state/host0",
1616 "org.freedesktop.DBus.Properties", "Set",
1617 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1618 std::variant<std::string>{command});
1619 }
1620 else
1621 {
1622 crow::connections::systemBus->async_method_call(
1623 [asyncResp, resetType](const boost::system::error_code ec) {
1624 if (ec)
1625 {
1626 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1627 if (ec.value() == boost::asio::error::invalid_argument)
1628 {
1629 messages::actionParameterNotSupported(
1630 asyncResp->res, resetType, "Reset");
1631 }
1632 else
1633 {
1634 messages::internalError(asyncResp->res);
1635 }
1636 return;
1637 }
1638 messages::success(asyncResp->res);
1639 },
1640 "xyz.openbmc_project.State.Chassis",
1641 "/xyz/openbmc_project/state/chassis0",
1642 "org.freedesktop.DBus.Properties", "Set",
1643 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1644 std::variant<std::string>{command});
1645 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001646 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001647 /**
1648 * Function transceives data with dbus directly.
1649 */
1650 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1651 {
1652 constexpr char const *serviceName =
1653 "xyz.openbmc_project.Control.Host.NMI";
1654 constexpr char const *objectPath =
1655 "/xyz/openbmc_project/control/host0/nmi";
1656 constexpr char const *interfaceName =
1657 "xyz.openbmc_project.Control.Host.NMI";
1658 constexpr char const *method = "NMI";
1659
1660 crow::connections::systemBus->async_method_call(
1661 [asyncResp](const boost::system::error_code ec) {
1662 if (ec)
1663 {
1664 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1665 messages::internalError(asyncResp->res);
1666 return;
1667 }
1668 messages::success(asyncResp->res);
1669 },
1670 serviceName, objectPath, interfaceName, method);
1671 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001672};
1673
1674/**
Ed Tanous66173382018-08-15 18:20:59 -07001675 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001676 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001677class Systems : public Node
1678{
1679 public:
1680 /*
1681 * Default Constructor
1682 */
Ed Tanous029573d2019-02-01 10:57:49 -08001683 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001684 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001685 entityPrivileges = {
1686 {boost::beast::http::verb::get, {{"Login"}}},
1687 {boost::beast::http::verb::head, {{"Login"}}},
1688 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1689 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1690 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1691 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001692 }
1693
Ed Tanous1abe55e2018-09-05 08:30:59 -07001694 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001695 /**
1696 * Functions triggers appropriate requests on DBus
1697 */
1698 void doGet(crow::Response &res, const crow::Request &req,
1699 const std::vector<std::string> &params) override
1700 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301701 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001702 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001703 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001704 res.jsonValue["SystemType"] = "Physical";
1705 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001706 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1707 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001708 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001709 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001710 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001711
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001712 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001713 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001714 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001715 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001716 res.jsonValue["Storage"] = {
1717 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001718
Ed Tanouscc340dd2018-08-29 13:43:38 -07001719 // TODO Need to support ForceRestart.
1720 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1721 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001722 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001723 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001724 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001725 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001726
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001727 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001728 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001729
Carol Wangd82a3ac2019-11-21 13:56:38 +08001730 res.jsonValue["Bios"] = {
1731 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1732
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001733 res.jsonValue["Links"]["ManagedBy"] = {
1734 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1735
1736 res.jsonValue["Status"] = {
1737 {"Health", "OK"},
1738 {"State", "Enabled"},
1739 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001740 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001741
James Feiste284a7c2019-11-20 16:20:23 -08001742 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001743 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001744 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001745 "xyz.openbmc_project.Inventory.Item.Drive",
1746 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001747
1748 auto health = std::make_shared<HealthPopulate>(asyncResp);
1749 crow::connections::systemBus->async_method_call(
1750 [health](const boost::system::error_code ec,
1751 std::vector<std::string> &resp) {
1752 if (ec)
1753 {
1754 // no inventory
1755 return;
1756 }
1757
1758 health->inventory = std::move(resp);
1759 },
1760 "xyz.openbmc_project.ObjectMapper",
1761 "/xyz/openbmc_project/object_mapper",
1762 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1763 int32_t(0), inventoryForSystems);
1764
1765 health->populate();
1766
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001767 getMainChassisId(asyncResp, [](const std::string &chassisId,
1768 std::shared_ptr<AsyncResp> aRsp) {
1769 aRsp->res.jsonValue["Links"]["Chassis"] = {
1770 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1771 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301772
1773 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001774 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001775 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301776 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001777 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001778 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001779 getPowerRestorePolicy(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301780#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1781 getProvisioningStatus(asyncResp);
1782#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001783 }
1784
Ed Tanous1abe55e2018-09-05 08:30:59 -07001785 void doPatch(crow::Response &res, const crow::Request &req,
1786 const std::vector<std::string> &params) override
1787 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301788 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301789 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001790 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001791 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001792 auto asyncResp = std::make_shared<AsyncResp>(res);
1793
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001794 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001795 bootProps, "WatchdogTimer", wdtTimerProps,
1796 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001797 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001798 return;
1799 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301800
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001801 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001802
1803 if (wdtTimerProps)
1804 {
1805 std::optional<bool> wdtEnable;
1806 std::optional<std::string> wdtTimeOutAction;
1807
1808 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1809 "FunctionEnabled", wdtEnable,
1810 "TimeoutAction", wdtTimeOutAction))
1811 {
1812 return;
1813 }
1814 setWDTProperties(asyncResp, std::move(wdtEnable),
1815 std::move(wdtTimeOutAction));
1816 }
1817
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301818 if (bootProps)
1819 {
1820 std::optional<std::string> bootSource;
1821 std::optional<std::string> bootEnable;
1822
1823 if (!json_util::readJson(*bootProps, asyncResp->res,
1824 "BootSourceOverrideTarget", bootSource,
1825 "BootSourceOverrideEnabled", bootEnable))
1826 {
1827 return;
1828 }
1829 setBootProperties(asyncResp, std::move(bootSource),
1830 std::move(bootEnable));
1831 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001832
Ed Tanous9712f8a2018-09-21 13:38:49 -07001833 if (indicatorLed)
1834 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301835 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001836 }
George Liuc6a620f2020-04-10 17:18:11 +08001837
1838 if (powerRestorePolicy)
1839 {
1840 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
1841 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001842 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001843};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001844} // namespace redfish