blob: 628c51a819297fe800625992a506021b8fa17314 [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 =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500230 std::get_if<uint32_t>(
231 &property.second);
Cheng C Yang5fd7ba62019-11-28 15:58:08 +0800232 if (value == nullptr)
233 {
234 BMCWEB_LOG_DEBUG
235 << "Find incorrect type of "
236 "MemorySize";
237 continue;
238 }
239 nlohmann::json &totalMemory =
240 aResp->res
241 .jsonValue["MemorySummar"
242 "y"]
243 ["TotalSystemMe"
244 "moryGiB"];
245 uint64_t *preValue =
246 totalMemory
247 .get_ptr<uint64_t *>();
248 if (preValue == nullptr)
249 {
250 continue;
251 }
252 aResp->res
253 .jsonValue["MemorySummary"]
254 ["TotalSystemMemoryGi"
255 "B"] =
256 *value / (1024 * 1024) +
257 *preValue;
258 aResp->res
259 .jsonValue["MemorySummary"]
260 ["Status"]["State"] =
261 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700262 }
Ed Tanous029573d2019-02-01 10:57:49 -0800263 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500264 else
265 {
266 auto getDimmProperties =
267 [aResp](
268 const boost::system::error_code
269 ec,
270 const std::variant<bool>
271 &dimmState) {
272 if (ec)
273 {
274 BMCWEB_LOG_ERROR
275 << "DBUS response "
276 "error "
277 << ec;
278 return;
279 }
280 updateDimmProperties(aResp,
281 dimmState);
282 };
283 crow::connections::systemBus
284 ->async_method_call(
285 std::move(getDimmProperties),
286 service, path,
287 "org.freedesktop.DBus."
288 "Properties",
289 "Get",
290 "xyz.openbmc_project.State."
291 "Decorator.OperationalStatus",
292 "Functional");
293 }
Ed Tanous029573d2019-02-01 10:57:49 -0800294 },
295 connection.first, path,
296 "org.freedesktop.DBus.Properties", "GetAll",
297 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700298
299 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800300 }
301 else if (interfaceName ==
302 "xyz.openbmc_project.Inventory.Item.Cpu")
303 {
304 BMCWEB_LOG_DEBUG
305 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500306
Ed Tanous029573d2019-02-01 10:57:49 -0800307 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500308 [aResp, service{connection.first},
309 path(std::move(path))](
310 const boost::system::error_code ec,
311 const std::vector<
312 std::pair<std::string, VariantType>>
313 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800314 if (ec)
315 {
316 BMCWEB_LOG_ERROR
317 << "DBUS response error " << ec;
318 messages::internalError(aResp->res);
319 return;
320 }
321 BMCWEB_LOG_DEBUG << "Got "
322 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500323 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700324
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500325 if (properties.size() > 0)
326 {
327 for (const auto &property : properties)
328 {
329 if (property.first ==
330 "ProcessorFamily")
331 {
332 const std::string *value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500333 std::get_if<std::string>(
334 &property.second);
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500335 if (value != nullptr)
336 {
337 nlohmann::json
338 &procSummary =
339 aResp->res.jsonValue
340 ["ProcessorSumm"
341 "ary"];
342 nlohmann::json &procCount =
343 procSummary["Count"];
James Feistb4b95952019-12-05 15:01:55 -0800344
345 auto procCountPtr =
346 procCount.get_ptr<
347 nlohmann::json::
348 number_integer_t
349 *>();
350 if (procCountPtr != nullptr)
351 {
352 // shouldn't be possible
353 // to be nullptr
354 *procCountPtr += 1;
355 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500356 procSummary["Status"]
357 ["State"] =
358 "Enabled";
359 procSummary["Model"] =
360 *value;
361 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700362 }
363 }
Ed Tanous029573d2019-02-01 10:57:49 -0800364 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500365 else
366 {
367 auto getCpuPresenceState =
368 [aResp](
369 const boost::system::error_code
370 ec,
371 const std::variant<bool>
372 &cpuPresenceCheck) {
373 if (ec)
374 {
375 BMCWEB_LOG_ERROR
376 << "DBUS response "
377 "error "
378 << ec;
379 return;
380 }
381 modifyCpuPresenceState(
382 aResp, cpuPresenceCheck);
383 };
384
385 auto getCpuFunctionalState =
386 [aResp](
387 const boost::system::error_code
388 ec,
389 const std::variant<bool>
390 &cpuFunctionalCheck) {
391 if (ec)
392 {
393 BMCWEB_LOG_ERROR
394 << "DBUS response "
395 "error "
396 << ec;
397 return;
398 }
399 modifyCpuFunctionalState(
400 aResp, cpuFunctionalCheck);
401 };
402 // Get the Presence of CPU
403 crow::connections::systemBus
404 ->async_method_call(
405 std::move(getCpuPresenceState),
406 service, path,
407 "org.freedesktop.DBus."
408 "Properties",
409 "Get",
410 "xyz.openbmc_project.Inventory."
411 "Item",
412 "Present");
413
414 // Get the Functional State
415 crow::connections::systemBus
416 ->async_method_call(
417 std::move(
418 getCpuFunctionalState),
419 service, path,
420 "org.freedesktop.DBus."
421 "Properties",
422 "Get",
423 "xyz.openbmc_project.State."
424 "Decorator."
425 "OperationalStatus",
426 "Functional");
427
428 // Get the MODEL from
429 // xyz.openbmc_project.Inventory.Decorator.Asset
430 // support it later as Model is Empty
431 // currently.
432 }
Ed Tanous029573d2019-02-01 10:57:49 -0800433 },
434 connection.first, path,
435 "org.freedesktop.DBus.Properties", "GetAll",
436 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700437
438 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800439 }
440 else if (interfaceName ==
441 "xyz.openbmc_project.Common.UUID")
442 {
443 BMCWEB_LOG_DEBUG
444 << "Found UUID, now get its properties.";
445 crow::connections::systemBus->async_method_call(
446 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700447 const std::vector<
448 std::pair<std::string, VariantType>>
449 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800450 if (ec)
451 {
452 BMCWEB_LOG_DEBUG
453 << "DBUS response error " << ec;
454 messages::internalError(aResp->res);
455 return;
456 }
457 BMCWEB_LOG_DEBUG << "Got "
458 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500459 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800460 for (const std::pair<std::string,
461 VariantType>
462 &property : properties)
463 {
Ed Tanous029573d2019-02-01 10:57:49 -0800464 if (property.first == "UUID")
465 {
466 const std::string *value =
Patrick Williams8d78b7a2020-05-13 11:24:20 -0500467 std::get_if<std::string>(
468 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700469
Ed Tanous029573d2019-02-01 10:57:49 -0800470 if (value != nullptr)
471 {
472 std::string valueStr = *value;
473 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700474 {
Ed Tanous029573d2019-02-01 10:57:49 -0800475 valueStr.insert(8, 1, '-');
476 valueStr.insert(13, 1, '-');
477 valueStr.insert(18, 1, '-');
478 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700479 }
Ed Tanous029573d2019-02-01 10:57:49 -0800480 BMCWEB_LOG_DEBUG << "UUID = "
481 << valueStr;
482 aResp->res.jsonValue["UUID"] =
483 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700484 }
485 }
Ed Tanous029573d2019-02-01 10:57:49 -0800486 }
487 },
488 connection.first, path,
489 "org.freedesktop.DBus.Properties", "GetAll",
490 "xyz.openbmc_project.Common.UUID");
491 }
492 else if (interfaceName ==
493 "xyz.openbmc_project.Inventory.Item.System")
494 {
495 crow::connections::systemBus->async_method_call(
496 [aResp](const boost::system::error_code ec,
497 const std::vector<
498 std::pair<std::string, VariantType>>
499 &propertiesList) {
500 if (ec)
501 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700502 // doesn't have to include this
503 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800504 return;
505 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500506 BMCWEB_LOG_DEBUG
507 << "Got " << propertiesList.size()
508 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800509 for (const std::pair<std::string,
510 VariantType>
511 &property : propertiesList)
512 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600513 const std::string &propertyName =
514 property.first;
515 if ((propertyName == "PartNumber") ||
516 (propertyName == "SerialNumber") ||
517 (propertyName == "Manufacturer") ||
518 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800519 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600520 const std::string *value =
521 std::get_if<std::string>(
522 &property.second);
523 if (value != nullptr)
524 {
525 aResp->res
526 .jsonValue[propertyName] =
527 *value;
528 }
Ed Tanous029573d2019-02-01 10:57:49 -0800529 }
530 }
Gunnar Millsc1e236a2020-04-14 21:36:33 -0500531
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600532 // Grab the bios version
533 fw_util::getActiveFwVersion(
534 aResp, fw_util::biosPurpose,
535 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800536 },
537 connection.first, path,
538 "org.freedesktop.DBus.Properties", "GetAll",
539 "xyz.openbmc_project.Inventory.Decorator."
540 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700541
542 crow::connections::systemBus->async_method_call(
543 [aResp](
544 const boost::system::error_code ec,
545 const std::variant<std::string> &property) {
546 if (ec)
547 {
548 // doesn't have to include this
549 // interface
550 return;
551 }
552
553 const std::string *value =
554 std::get_if<std::string>(&property);
555 if (value != nullptr)
556 {
557 aResp->res.jsonValue["AssetTag"] =
558 *value;
559 }
560 },
561 connection.first, path,
562 "org.freedesktop.DBus.Properties", "Get",
563 "xyz.openbmc_project.Inventory.Decorator."
564 "AssetTag",
565 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700566 }
567 }
568 }
569 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700570 },
571 "xyz.openbmc_project.ObjectMapper",
572 "/xyz/openbmc_project/object_mapper",
573 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700574 "/xyz/openbmc_project/inventory", int32_t(0),
575 std::array<const char *, 5>{
576 "xyz.openbmc_project.Inventory.Decorator.Asset",
577 "xyz.openbmc_project.Inventory.Item.Cpu",
578 "xyz.openbmc_project.Inventory.Item.Dimm",
579 "xyz.openbmc_project.Inventory.Item.System",
580 "xyz.openbmc_project.Common.UUID",
581 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700582}
583
584/**
Ed Tanous6c34de42018-08-29 13:37:36 -0700585 * @brief Retrieves host state properties over dbus
586 *
587 * @param[in] aResp Shared pointer for completing asynchronous calls.
588 *
589 * @return None.
590 */
591void getHostState(std::shared_ptr<AsyncResp> aResp)
592{
593 BMCWEB_LOG_DEBUG << "Get host information.";
594 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800595 [aResp](const boost::system::error_code ec,
596 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700597 if (ec)
598 {
599 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700600 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700601 return;
602 }
Ed Tanous66173382018-08-15 18:20:59 -0700603
Ed Tanousabf2add2019-01-22 16:40:12 -0800604 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700605 BMCWEB_LOG_DEBUG << "Host state: " << *s;
606 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700607 {
Ed Tanous66173382018-08-15 18:20:59 -0700608 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800609 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700610 {
Ed Tanous66173382018-08-15 18:20:59 -0700611 aResp->res.jsonValue["PowerState"] = "On";
612 aResp->res.jsonValue["Status"]["State"] = "Enabled";
613 }
Andrew Geissler83935af2020-02-13 10:24:53 -0600614 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Gunnar Mills8c888602020-05-01 14:25:09 -0500615 "Quiesced")
616 {
617 aResp->res.jsonValue["PowerState"] = "On";
618 aResp->res.jsonValue["Status"]["State"] = "Quiesced";
619 }
620 else if (*s == "xyz.openbmc_project.State.Host.HostState."
Andrew Geissler83935af2020-02-13 10:24:53 -0600621 "DiagnosticMode")
622 {
623 aResp->res.jsonValue["PowerState"] = "On";
624 aResp->res.jsonValue["Status"]["State"] = "InTest";
625 }
Ed Tanous66173382018-08-15 18:20:59 -0700626 else
627 {
628 aResp->res.jsonValue["PowerState"] = "Off";
629 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700630 }
631 }
632 },
633 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700634 "org.freedesktop.DBus.Properties", "Get",
635 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700636}
637
638/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530639 * @brief Traslates boot source DBUS property value to redfish.
640 *
641 * @param[in] dbusSource The boot source in DBUS speak.
642 *
643 * @return Returns as a string, the boot source in Redfish terms. If translation
644 * cannot be done, returns an empty string.
645 */
646static std::string dbusToRfBootSource(const std::string &dbusSource)
647{
648 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
649 {
650 return "None";
651 }
652 else if (dbusSource ==
653 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
654 {
655 return "Hdd";
656 }
657 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530658 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530659 {
660 return "Cd";
661 }
662 else if (dbusSource ==
663 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
664 {
665 return "Pxe";
666 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700667 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700668 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700669 {
670 return "Usb";
671 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530672 else
673 {
674 return "";
675 }
676}
677
678/**
679 * @brief Traslates boot mode DBUS property value to redfish.
680 *
681 * @param[in] dbusMode The boot mode in DBUS speak.
682 *
683 * @return Returns as a string, the boot mode in Redfish terms. If translation
684 * cannot be done, returns an empty string.
685 */
686static std::string dbusToRfBootMode(const std::string &dbusMode)
687{
688 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
689 {
690 return "None";
691 }
692 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
693 {
694 return "Diags";
695 }
696 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
697 {
698 return "BiosSetup";
699 }
700 else
701 {
702 return "";
703 }
704}
705
706/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700707 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530708 *
709 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700710 * @param[out] bootSource The DBus source
711 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700713 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530714 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700715static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
716 const std::string &rfSource,
717 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530718{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700719 // The caller has initialized the bootSource and bootMode to:
720 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
721 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
722 // Only modify the bootSource/bootMode variable needed to achieve the
723 // desired boot action.
724
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530725 if (rfSource == "None")
726 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700727 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530728 }
729 else if (rfSource == "Pxe")
730 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700731 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
732 }
733 else if (rfSource == "Hdd")
734 {
735 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
736 }
737 else if (rfSource == "Diags")
738 {
739 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
740 }
741 else if (rfSource == "Cd")
742 {
743 bootSource =
744 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
745 }
746 else if (rfSource == "BiosSetup")
747 {
748 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530749 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700750 else if (rfSource == "Usb")
751 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700752 bootSource =
753 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700754 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530755 else
756 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700757 BMCWEB_LOG_DEBUG << "Invalid property value for "
758 "BootSourceOverrideTarget: "
759 << bootSource;
760 messages::propertyValueNotInList(aResp->res, rfSource,
761 "BootSourceTargetOverride");
762 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530763 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700764 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530765}
766
767/**
768 * @brief Retrieves boot mode over DBUS and fills out the response
769 *
770 * @param[in] aResp Shared pointer for generating response message.
771 * @param[in] bootDbusObj The dbus object to query for boot properties.
772 *
773 * @return None.
774 */
775static void getBootMode(std::shared_ptr<AsyncResp> aResp,
776 std::string bootDbusObj)
777{
778 crow::connections::systemBus->async_method_call(
779 [aResp](const boost::system::error_code ec,
780 const std::variant<std::string> &bootMode) {
781 if (ec)
782 {
783 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
784 messages::internalError(aResp->res);
785 return;
786 }
787
788 const std::string *bootModeStr =
789 std::get_if<std::string>(&bootMode);
790
791 if (!bootModeStr)
792 {
793 messages::internalError(aResp->res);
794 return;
795 }
796
797 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
798
799 // TODO (Santosh): Do we need to support override mode?
800 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
801 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
802 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700803 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530804
805 if (*bootModeStr !=
806 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
807 {
808 auto rfMode = dbusToRfBootMode(*bootModeStr);
809 if (!rfMode.empty())
810 {
811 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
812 rfMode;
813 }
814 }
815
816 // If the BootSourceOverrideTarget is still "None" at the end,
817 // reset the BootSourceOverrideEnabled to indicate that
818 // overrides are disabled
819 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
820 "None")
821 {
822 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
823 "Disabled";
824 }
825 },
826 "xyz.openbmc_project.Settings", bootDbusObj,
827 "org.freedesktop.DBus.Properties", "Get",
828 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
829}
830
831/**
832 * @brief Retrieves boot source over DBUS
833 *
834 * @param[in] aResp Shared pointer for generating response message.
835 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
836 *
837 * @return None.
838 */
839static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
840{
841 std::string bootDbusObj =
842 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
843 : "/xyz/openbmc_project/control/host0/boot";
844
845 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
846 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
847 (oneTimeEnabled) ? "Once" : "Continuous";
848
849 crow::connections::systemBus->async_method_call(
850 [aResp, bootDbusObj](const boost::system::error_code ec,
851 const std::variant<std::string> &bootSource) {
852 if (ec)
853 {
854 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
855 messages::internalError(aResp->res);
856 return;
857 }
858
859 const std::string *bootSourceStr =
860 std::get_if<std::string>(&bootSource);
861
862 if (!bootSourceStr)
863 {
864 messages::internalError(aResp->res);
865 return;
866 }
867 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
868
869 auto rfSource = dbusToRfBootSource(*bootSourceStr);
870 if (!rfSource.empty())
871 {
872 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
873 rfSource;
874 }
875 },
876 "xyz.openbmc_project.Settings", bootDbusObj,
877 "org.freedesktop.DBus.Properties", "Get",
878 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
879 getBootMode(std::move(aResp), std::move(bootDbusObj));
880}
881
882/**
883 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
884 * get boot source and boot mode.
885 *
886 * @param[in] aResp Shared pointer for generating response message.
887 *
888 * @return None.
889 */
890static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
891{
892 BMCWEB_LOG_DEBUG << "Get boot information.";
893
894 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800895 [aResp](const boost::system::error_code ec,
Patrick Williams19bd78d2020-05-13 17:38:24 -0500896 const std::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530897 if (ec)
898 {
899 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700900 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530901 return;
902 }
903
904 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
905
906 if (!oneTimePtr)
907 {
908 messages::internalError(aResp->res);
909 return;
910 }
911 getBootSource(aResp, *oneTimePtr);
912 },
913 "xyz.openbmc_project.Settings",
914 "/xyz/openbmc_project/control/host0/boot/one_time",
915 "org.freedesktop.DBus.Properties", "Get",
916 "xyz.openbmc_project.Object.Enable", "Enabled");
917}
918
919/**
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -0500920 * @brief Retrieves Automatic Retry properties. Known on D-Bus as AutoReboot.
921 *
922 * @param[in] aResp Shared pointer for generating response message.
923 *
924 * @return None.
925 */
926void getAutomaticRetry(std::shared_ptr<AsyncResp> aResp)
927{
928 BMCWEB_LOG_DEBUG << "Get Automatic Retry policy";
929
930 crow::connections::systemBus->async_method_call(
931 [aResp](const boost::system::error_code ec,
932 std::variant<bool> &autoRebootEnabled) {
933 if (ec)
934 {
935 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
936 return;
937 }
938
939 const bool *autoRebootEnabledPtr =
940 std::get_if<bool>(&autoRebootEnabled);
941
942 if (!autoRebootEnabledPtr)
943 {
944 messages::internalError(aResp->res);
945 return;
946 }
947
948 BMCWEB_LOG_DEBUG << "Auto Reboot: " << *autoRebootEnabledPtr;
949 if (*autoRebootEnabledPtr == true)
950 {
951 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
952 "RetryAttempts";
953 // If AutomaticRetry (AutoReboot) is enabled see how many
954 // attempts are left
955 crow::connections::systemBus->async_method_call(
956 [aResp](const boost::system::error_code ec,
957 std::variant<uint32_t> &autoRebootAttemptsLeft) {
958 if (ec)
959 {
960 BMCWEB_LOG_DEBUG << "D-BUS response error " << ec;
961 return;
962 }
963
964 const uint32_t *autoRebootAttemptsLeftPtr =
965 std::get_if<uint32_t>(&autoRebootAttemptsLeft);
966
967 if (!autoRebootAttemptsLeftPtr)
968 {
969 messages::internalError(aResp->res);
970 return;
971 }
972
973 BMCWEB_LOG_DEBUG << "Auto Reboot Attempts Left: "
974 << *autoRebootAttemptsLeftPtr;
975
976 aResp->res
977 .jsonValue["Boot"]
978 ["RemainingAutomaticRetryAttempts"] =
979 *autoRebootAttemptsLeftPtr;
980 },
981 "xyz.openbmc_project.State.Host",
982 "/xyz/openbmc_project/state/host0",
983 "org.freedesktop.DBus.Properties", "Get",
984 "xyz.openbmc_project.Control.Boot.RebootAttempts",
985 "AttemptsLeft");
986 }
987 else
988 {
989 aResp->res.jsonValue["Boot"]["AutomaticRetryConfig"] =
990 "Disabled";
991 }
992
993 // Not on D-Bus. Hardcoded here:
994 // https://github.com/openbmc/phosphor-state-manager/blob/1dbbef42675e94fb1f78edb87d6b11380260535a/meson_options.txt#L71
995 aResp->res.jsonValue["Boot"]["AutomaticRetryAttempts"] = 3;
996 },
997 "xyz.openbmc_project.Settings",
998 "/xyz/openbmc_project/control/host0/auto_reboot",
999 "org.freedesktop.DBus.Properties", "Get",
1000 "xyz.openbmc_project.Control.Boot.RebootPolicy", "AutoReboot");
1001}
1002
1003/**
George Liuc6a620f2020-04-10 17:18:11 +08001004 * @brief Retrieves power restore policy over DBUS.
1005 *
1006 * @param[in] aResp Shared pointer for generating response message.
1007 *
1008 * @return None.
1009 */
1010void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
1011{
1012 BMCWEB_LOG_DEBUG << "Get power restore policy";
1013
1014 crow::connections::systemBus->async_method_call(
1015 [aResp](const boost::system::error_code ec,
Patrick Williams19bd78d2020-05-13 17:38:24 -05001016 std::variant<std::string> &policy) {
George Liuc6a620f2020-04-10 17:18:11 +08001017 if (ec)
1018 {
1019 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1020 return;
1021 }
1022
1023 const boost::container::flat_map<std::string, std::string>
1024 policyMaps = {
1025 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1026 "AlwaysOn",
1027 "AlwaysOn"},
1028 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1029 "AlwaysOff",
1030 "AlwaysOff"},
1031 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1032 "LastState",
1033 "LastState"}};
1034
1035 const std::string *policyPtr = std::get_if<std::string>(&policy);
1036
1037 if (!policyPtr)
1038 {
1039 messages::internalError(aResp->res);
1040 return;
1041 }
1042
1043 auto policyMapsIt = policyMaps.find(*policyPtr);
1044 if (policyMapsIt == policyMaps.end())
1045 {
1046 messages::internalError(aResp->res);
1047 return;
1048 }
1049
1050 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
1051 },
1052 "xyz.openbmc_project.Settings",
1053 "/xyz/openbmc_project/control/host0/power_restore_policy",
1054 "org.freedesktop.DBus.Properties", "Get",
1055 "xyz.openbmc_project.Control.Power.RestorePolicy",
1056 "PowerRestorePolicy");
1057}
1058
1059/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301060 * @brief Sets boot properties into DBUS object(s).
1061 *
1062 * @param[in] aResp Shared pointer for generating response message.
1063 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1064 * @param[in] bootSource The boot source to set.
1065 * @param[in] bootEnable The source override "enable" to set.
1066 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001067 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301068 */
1069static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1070 bool oneTimeEnabled,
1071 std::optional<std::string> bootSource,
1072 std::optional<std::string> bootEnable)
1073{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001074 std::string bootSourceStr =
1075 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1076 std::string bootModeStr =
1077 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301078 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001079 bool useBootSource = true;
1080
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301081 // Validate incoming parameters
1082 if (bootEnable)
1083 {
1084 if (*bootEnable == "Once")
1085 {
1086 oneTimeSetting = true;
1087 }
1088 else if (*bootEnable == "Continuous")
1089 {
1090 oneTimeSetting = false;
1091 }
1092 else if (*bootEnable == "Disabled")
1093 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001094 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301095 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001096 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301097 }
1098 else
1099 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301100 BMCWEB_LOG_DEBUG << "Unsupported value for "
1101 "BootSourceOverrideEnabled: "
1102 << *bootEnable;
1103 messages::propertyValueNotInList(aResp->res, *bootEnable,
1104 "BootSourceOverrideEnabled");
1105 return;
1106 }
1107 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301108
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001109 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301110 {
1111 // Source target specified
1112 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1113 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001114 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1115 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301116 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001117 BMCWEB_LOG_DEBUG
1118 << "Invalid property value for BootSourceOverrideTarget: "
1119 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301120 messages::propertyValueNotInList(aResp->res, *bootSource,
1121 "BootSourceTargetOverride");
1122 return;
1123 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001124 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301125
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001126 // Act on validated parameters
1127 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1128 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1129 const char *bootObj =
1130 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1131 : "/xyz/openbmc_project/control/host0/boot";
1132
1133 crow::connections::systemBus->async_method_call(
1134 [aResp](const boost::system::error_code ec) {
1135 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301136 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001137 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1138 messages::internalError(aResp->res);
1139 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301140 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001141 BMCWEB_LOG_DEBUG << "Boot source update done.";
1142 },
1143 "xyz.openbmc_project.Settings", bootObj,
1144 "org.freedesktop.DBus.Properties", "Set",
1145 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1146 std::variant<std::string>(bootSourceStr));
1147
1148 crow::connections::systemBus->async_method_call(
1149 [aResp](const boost::system::error_code ec) {
1150 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301151 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001152 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1153 messages::internalError(aResp->res);
1154 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301155 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001156 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1157 },
1158 "xyz.openbmc_project.Settings", bootObj,
1159 "org.freedesktop.DBus.Properties", "Set",
1160 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1161 std::variant<std::string>(bootModeStr));
1162
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301163 crow::connections::systemBus->async_method_call(
1164 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1165 if (ec)
1166 {
1167 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1168 messages::internalError(aResp->res);
1169 return;
1170 }
1171 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1172 },
1173 "xyz.openbmc_project.Settings",
1174 "/xyz/openbmc_project/control/host0/boot/one_time",
1175 "org.freedesktop.DBus.Properties", "Set",
1176 "xyz.openbmc_project.Object.Enable", "Enabled",
1177 std::variant<bool>(oneTimeSetting));
1178}
1179
1180/**
1181 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1182 * set boot source/boot mode properties.
1183 *
1184 * @param[in] aResp Shared pointer for generating response message.
1185 * @param[in] bootSource The boot source from incoming RF request.
1186 * @param[in] bootEnable The boot override enable from incoming RF request.
1187 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001188 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301189 */
1190static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1191 std::optional<std::string> bootSource,
1192 std::optional<std::string> bootEnable)
1193{
1194 BMCWEB_LOG_DEBUG << "Set boot information.";
1195
1196 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001197 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001198 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
1199 const std::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301200 if (ec)
1201 {
1202 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1203 messages::internalError(aResp->res);
1204 return;
1205 }
1206
1207 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1208
1209 if (!oneTimePtr)
1210 {
1211 messages::internalError(aResp->res);
1212 return;
1213 }
1214
1215 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1216
1217 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1218 std::move(bootEnable));
1219 },
1220 "xyz.openbmc_project.Settings",
1221 "/xyz/openbmc_project/control/host0/boot/one_time",
1222 "org.freedesktop.DBus.Properties", "Get",
1223 "xyz.openbmc_project.Object.Enable", "Enabled");
1224}
1225
George Liuc6a620f2020-04-10 17:18:11 +08001226/**
1227 * @brief Sets power restore policy properties.
1228 *
1229 * @param[in] aResp Shared pointer for generating response message.
1230 * @param[in] policy power restore policy properties from request.
1231 *
1232 * @return None.
1233 */
1234static void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
1235 std::optional<std::string> policy)
1236{
1237 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1238
1239 const boost::container::flat_map<std::string, std::string> policyMaps = {
1240 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1241 "AlwaysOn"},
1242 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1243 "AlwaysOff"},
1244 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1245 "LastState"}};
1246
1247 std::string powerRestorPolicy;
1248
1249 auto policyMapsIt = policyMaps.find(*policy);
1250 if (policyMapsIt == policyMaps.end())
1251 {
1252 messages::internalError(aResp->res);
1253 return;
1254 }
1255
1256 powerRestorPolicy = policyMapsIt->second;
1257
1258 crow::connections::systemBus->async_method_call(
1259 [aResp](const boost::system::error_code ec) {
1260 if (ec)
1261 {
1262 messages::internalError(aResp->res);
1263 return;
1264 }
1265 },
1266 "xyz.openbmc_project.Settings",
1267 "/xyz/openbmc_project/control/host0/power_restore_policy",
1268 "org.freedesktop.DBus.Properties", "Set",
1269 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1270 std::variant<std::string>(powerRestorPolicy));
1271}
1272
AppaRao Pulia6349912019-10-18 17:16:08 +05301273#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1274/**
1275 * @brief Retrieves provisioning status
1276 *
1277 * @param[in] aResp Shared pointer for completing asynchronous calls.
1278 *
1279 * @return None.
1280 */
1281void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1282{
1283 BMCWEB_LOG_DEBUG << "Get OEM information.";
1284 crow::connections::systemBus->async_method_call(
1285 [aResp](const boost::system::error_code ec,
1286 const std::vector<std::pair<std::string, VariantType>>
1287 &propertiesList) {
1288 if (ec)
1289 {
1290 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1291 messages::internalError(aResp->res);
1292 return;
1293 }
1294
1295 const bool *provState = nullptr;
1296 const bool *lockState = nullptr;
1297 for (const std::pair<std::string, VariantType> &property :
1298 propertiesList)
1299 {
1300 if (property.first == "UfmProvisioned")
1301 {
1302 provState = std::get_if<bool>(&property.second);
1303 }
1304 else if (property.first == "UfmLocked")
1305 {
1306 lockState = std::get_if<bool>(&property.second);
1307 }
1308 }
1309
1310 if ((provState == nullptr) || (lockState == nullptr))
1311 {
1312 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1313 messages::internalError(aResp->res);
1314 return;
1315 }
1316
1317 nlohmann::json &oemPFR =
1318 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1319 if (*provState == true)
1320 {
1321 if (*lockState == true)
1322 {
1323 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1324 }
1325 else
1326 {
1327 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1328 }
1329 }
1330 else
1331 {
1332 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1333 }
1334 },
1335 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1336 "org.freedesktop.DBus.Properties", "GetAll",
1337 "xyz.openbmc_project.PFR.Attributes");
1338}
1339#endif
1340
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301341/**
Yong Li51709ff2019-09-30 14:13:04 +08001342 * @brief Translates watchdog timeout action DBUS property value to redfish.
1343 *
1344 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1345 *
1346 * @return Returns as a string, the timeout action in Redfish terms. If
1347 * translation cannot be done, returns an empty string.
1348 */
1349static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1350{
1351 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1352 {
1353 return "None";
1354 }
1355 else if (dbusAction ==
1356 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1357 {
1358 return "ResetSystem";
1359 }
1360 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1361 {
1362 return "PowerDown";
1363 }
1364 else if (dbusAction ==
1365 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1366 {
1367 return "PowerCycle";
1368 }
1369
1370 return "";
1371}
1372
1373/**
Yong Lic45f0082019-10-10 14:19:01 +08001374 *@brief Translates timeout action from Redfish to DBUS property value.
1375 *
1376 *@param[in] rfAction The timeout action in Redfish.
1377 *
1378 *@return Returns as a string, the time_out action as expected by DBUS.
1379 *If translation cannot be done, returns an empty string.
1380 */
1381
1382static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1383{
1384 if (rfAction == "None")
1385 {
1386 return "xyz.openbmc_project.State.Watchdog.Action.None";
1387 }
1388 else if (rfAction == "PowerCycle")
1389 {
1390 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1391 }
1392 else if (rfAction == "PowerDown")
1393 {
1394 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1395 }
1396 else if (rfAction == "ResetSystem")
1397 {
1398 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1399 }
1400
1401 return "";
1402}
1403
1404/**
Yong Li51709ff2019-09-30 14:13:04 +08001405 * @brief Retrieves host watchdog timer properties over DBUS
1406 *
1407 * @param[in] aResp Shared pointer for completing asynchronous calls.
1408 *
1409 * @return None.
1410 */
1411void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1412{
1413 BMCWEB_LOG_DEBUG << "Get host watchodg";
1414 crow::connections::systemBus->async_method_call(
1415 [aResp](const boost::system::error_code ec,
1416 PropertiesType &properties) {
1417 if (ec)
1418 {
1419 // watchdog service is stopped
1420 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1421 return;
1422 }
1423
1424 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1425
1426 nlohmann::json &hostWatchdogTimer =
1427 aResp->res.jsonValue["HostWatchdogTimer"];
1428
1429 // watchdog service is running/enabled
1430 hostWatchdogTimer["Status"]["State"] = "Enabled";
1431
1432 for (const auto &property : properties)
1433 {
1434 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1435 if (property.first == "Enabled")
1436 {
1437 const bool *state = std::get_if<bool>(&property.second);
1438
1439 if (!state)
1440 {
1441 messages::internalError(aResp->res);
1442 continue;
1443 }
1444
1445 hostWatchdogTimer["FunctionEnabled"] = *state;
1446 }
1447 else if (property.first == "ExpireAction")
1448 {
1449 const std::string *s =
1450 std::get_if<std::string>(&property.second);
1451 if (!s)
1452 {
1453 messages::internalError(aResp->res);
1454 continue;
1455 }
1456
1457 std::string action = dbusToRfWatchdogAction(*s);
1458 if (action.empty())
1459 {
1460 messages::internalError(aResp->res);
1461 continue;
1462 }
1463 hostWatchdogTimer["TimeoutAction"] = action;
1464 }
1465 }
1466 },
1467 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1468 "org.freedesktop.DBus.Properties", "GetAll",
1469 "xyz.openbmc_project.State.Watchdog");
1470}
1471
1472/**
Yong Lic45f0082019-10-10 14:19:01 +08001473 * @brief Sets Host WatchDog Timer properties.
1474 *
1475 * @param[in] aResp Shared pointer for generating response message.
1476 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1477 * RF request.
1478 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1479 *
1480 * @return None.
1481 */
1482static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1483 const std::optional<bool> wdtEnable,
1484 const std::optional<std::string> &wdtTimeOutAction)
1485{
1486 BMCWEB_LOG_DEBUG << "Set host watchdog";
1487
1488 if (wdtTimeOutAction)
1489 {
1490 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1491 // check if TimeOut Action is Valid
1492 if (wdtTimeOutActStr.empty())
1493 {
1494 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1495 << *wdtTimeOutAction;
1496 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1497 "TimeoutAction");
1498 return;
1499 }
1500
1501 crow::connections::systemBus->async_method_call(
1502 [aResp](const boost::system::error_code ec) {
1503 if (ec)
1504 {
1505 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1506 messages::internalError(aResp->res);
1507 return;
1508 }
1509 },
1510 "xyz.openbmc_project.Watchdog",
1511 "/xyz/openbmc_project/watchdog/host0",
1512 "org.freedesktop.DBus.Properties", "Set",
1513 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1514 std::variant<std::string>(wdtTimeOutActStr));
1515 }
1516
1517 if (wdtEnable)
1518 {
1519 crow::connections::systemBus->async_method_call(
1520 [aResp](const boost::system::error_code ec) {
1521 if (ec)
1522 {
1523 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1524 messages::internalError(aResp->res);
1525 return;
1526 }
1527 },
1528 "xyz.openbmc_project.Watchdog",
1529 "/xyz/openbmc_project/watchdog/host0",
1530 "org.freedesktop.DBus.Properties", "Set",
1531 "xyz.openbmc_project.State.Watchdog", "Enabled",
1532 std::variant<bool>(*wdtEnable));
1533 }
1534}
1535
1536/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001537 * SystemsCollection derived class for delivering ComputerSystems Collection
1538 * Schema
1539 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001540class SystemsCollection : public Node
1541{
1542 public:
1543 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1544 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001545 entityPrivileges = {
1546 {boost::beast::http::verb::get, {{"Login"}}},
1547 {boost::beast::http::verb::head, {{"Login"}}},
1548 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1549 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1550 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1551 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1552 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001553
Ed Tanous1abe55e2018-09-05 08:30:59 -07001554 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001555 void doGet(crow::Response &res, const crow::Request &req,
1556 const std::vector<std::string> &params) override
1557 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001558 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001559 res.jsonValue["@odata.type"] =
1560 "#ComputerSystemCollection.ComputerSystemCollection";
1561 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001562 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001563
1564 crow::connections::systemBus->async_method_call(
1565 [asyncResp](const boost::system::error_code ec,
1566 const std::variant<std::string> &hostName) {
1567 nlohmann::json &iface_array =
1568 asyncResp->res.jsonValue["Members"];
1569 iface_array = nlohmann::json::array();
1570 auto &count = asyncResp->res.jsonValue["Members@odata.count"];
1571 count = 0;
1572 if (ec)
1573 {
1574 iface_array.push_back(
1575 {{"@odata.id", "/redfish/v1/Systems/system"}});
1576 count = iface_array.size();
1577 return;
1578 }
1579 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1580 iface_array.push_back(
1581 {{"@odata.id", "/redfish/v1/Systems/system"}});
1582 iface_array.push_back(
1583 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1584 count = iface_array.size();
1585 },
1586 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/vmi",
1587 "org.freedesktop.DBus.Properties", "Get",
1588 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001589 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001590};
1591
1592/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001593 * SystemActionsReset class supports handle POST method for Reset action.
1594 * The class retrieves and sends data directly to D-Bus.
1595 */
1596class SystemActionsReset : public Node
1597{
1598 public:
1599 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001600 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001601 {
1602 entityPrivileges = {
1603 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1604 }
1605
1606 private:
1607 /**
1608 * Function handles POST method request.
1609 * Analyzes POST body message before sends Reset request data to D-Bus.
1610 */
1611 void doPost(crow::Response &res, const crow::Request &req,
1612 const std::vector<std::string> &params) override
1613 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001614 auto asyncResp = std::make_shared<AsyncResp>(res);
1615
1616 std::string resetType;
1617 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001618 {
1619 return;
1620 }
1621
Jason M. Billsd22c8392019-06-03 13:59:03 -07001622 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001623 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001624 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001625 if (resetType == "On")
1626 {
1627 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001628 hostCommand = true;
1629 }
1630 else if (resetType == "ForceOff")
1631 {
1632 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1633 hostCommand = false;
1634 }
1635 else if (resetType == "ForceOn")
1636 {
1637 command = "xyz.openbmc_project.State.Host.Transition.On";
1638 hostCommand = true;
1639 }
1640 else if (resetType == "ForceRestart")
1641 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001642 command =
1643 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1644 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001645 }
1646 else if (resetType == "GracefulShutdown")
1647 {
1648 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001649 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001650 }
1651 else if (resetType == "GracefulRestart")
1652 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001653 command =
1654 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001655 hostCommand = true;
1656 }
1657 else if (resetType == "PowerCycle")
1658 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001659 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1660 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001661 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001662 else if (resetType == "Nmi")
1663 {
1664 doNMI(asyncResp);
1665 return;
1666 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001667 else
1668 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001669 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001670 return;
1671 }
1672
Jason M. Billsd22c8392019-06-03 13:59:03 -07001673 if (hostCommand)
1674 {
1675 crow::connections::systemBus->async_method_call(
1676 [asyncResp, resetType](const boost::system::error_code ec) {
1677 if (ec)
1678 {
1679 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1680 if (ec.value() == boost::asio::error::invalid_argument)
1681 {
1682 messages::actionParameterNotSupported(
1683 asyncResp->res, resetType, "Reset");
1684 }
1685 else
1686 {
1687 messages::internalError(asyncResp->res);
1688 }
1689 return;
1690 }
1691 messages::success(asyncResp->res);
1692 },
1693 "xyz.openbmc_project.State.Host",
1694 "/xyz/openbmc_project/state/host0",
1695 "org.freedesktop.DBus.Properties", "Set",
1696 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1697 std::variant<std::string>{command});
1698 }
1699 else
1700 {
1701 crow::connections::systemBus->async_method_call(
1702 [asyncResp, resetType](const boost::system::error_code ec) {
1703 if (ec)
1704 {
1705 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1706 if (ec.value() == boost::asio::error::invalid_argument)
1707 {
1708 messages::actionParameterNotSupported(
1709 asyncResp->res, resetType, "Reset");
1710 }
1711 else
1712 {
1713 messages::internalError(asyncResp->res);
1714 }
1715 return;
1716 }
1717 messages::success(asyncResp->res);
1718 },
1719 "xyz.openbmc_project.State.Chassis",
1720 "/xyz/openbmc_project/state/chassis0",
1721 "org.freedesktop.DBus.Properties", "Set",
1722 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1723 std::variant<std::string>{command});
1724 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001725 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001726 /**
1727 * Function transceives data with dbus directly.
1728 */
1729 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1730 {
1731 constexpr char const *serviceName =
1732 "xyz.openbmc_project.Control.Host.NMI";
1733 constexpr char const *objectPath =
1734 "/xyz/openbmc_project/control/host0/nmi";
1735 constexpr char const *interfaceName =
1736 "xyz.openbmc_project.Control.Host.NMI";
1737 constexpr char const *method = "NMI";
1738
1739 crow::connections::systemBus->async_method_call(
1740 [asyncResp](const boost::system::error_code ec) {
1741 if (ec)
1742 {
1743 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1744 messages::internalError(asyncResp->res);
1745 return;
1746 }
1747 messages::success(asyncResp->res);
1748 },
1749 serviceName, objectPath, interfaceName, method);
1750 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001751};
1752
1753/**
Ed Tanous66173382018-08-15 18:20:59 -07001754 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001755 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001756class Systems : public Node
1757{
1758 public:
1759 /*
1760 * Default Constructor
1761 */
Ed Tanous029573d2019-02-01 10:57:49 -08001762 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001763 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001764 entityPrivileges = {
1765 {boost::beast::http::verb::get, {{"Login"}}},
1766 {boost::beast::http::verb::head, {{"Login"}}},
1767 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1768 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1769 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1770 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001771 }
1772
Ed Tanous1abe55e2018-09-05 08:30:59 -07001773 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001774 /**
1775 * Functions triggers appropriate requests on DBus
1776 */
1777 void doGet(crow::Response &res, const crow::Request &req,
1778 const std::vector<std::string> &params) override
1779 {
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001780 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_11_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001781 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001782 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001783 res.jsonValue["SystemType"] = "Physical";
1784 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001785 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1786 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001787 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001788 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001789 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001790
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001791 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001792 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001793 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001794 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001795 res.jsonValue["Storage"] = {
1796 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001797
Ed Tanouscc340dd2018-08-29 13:43:38 -07001798 // TODO Need to support ForceRestart.
1799 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1800 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001801 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001802 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001803 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001804 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001805
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001806 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001807 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001808
Carol Wangd82a3ac2019-11-21 13:56:38 +08001809 res.jsonValue["Bios"] = {
1810 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1811
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001812 res.jsonValue["Links"]["ManagedBy"] = {
1813 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1814
1815 res.jsonValue["Status"] = {
1816 {"Health", "OK"},
1817 {"State", "Enabled"},
1818 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001819 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001820
James Feiste284a7c2019-11-20 16:20:23 -08001821 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001822 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001823 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001824 "xyz.openbmc_project.Inventory.Item.Drive",
1825 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001826
1827 auto health = std::make_shared<HealthPopulate>(asyncResp);
1828 crow::connections::systemBus->async_method_call(
1829 [health](const boost::system::error_code ec,
1830 std::vector<std::string> &resp) {
1831 if (ec)
1832 {
1833 // no inventory
1834 return;
1835 }
1836
1837 health->inventory = std::move(resp);
1838 },
1839 "xyz.openbmc_project.ObjectMapper",
1840 "/xyz/openbmc_project/object_mapper",
1841 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1842 int32_t(0), inventoryForSystems);
1843
1844 health->populate();
1845
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001846 getMainChassisId(asyncResp, [](const std::string &chassisId,
1847 std::shared_ptr<AsyncResp> aRsp) {
1848 aRsp->res.jsonValue["Links"]["Chassis"] = {
1849 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1850 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301851
1852 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001853 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001854 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301855 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001856 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001857 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001858 getPowerRestorePolicy(asyncResp);
Gunnar Mills6bd5a8d2020-05-16 18:49:33 -05001859 getAutomaticRetry(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301860#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1861 getProvisioningStatus(asyncResp);
1862#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001863 }
1864
Ed Tanous1abe55e2018-09-05 08:30:59 -07001865 void doPatch(crow::Response &res, const crow::Request &req,
1866 const std::vector<std::string> &params) override
1867 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301868 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301869 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001870 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001871 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001872 auto asyncResp = std::make_shared<AsyncResp>(res);
1873
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001874 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001875 bootProps, "WatchdogTimer", wdtTimerProps,
1876 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001877 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001878 return;
1879 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301880
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001881 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001882
1883 if (wdtTimerProps)
1884 {
1885 std::optional<bool> wdtEnable;
1886 std::optional<std::string> wdtTimeOutAction;
1887
1888 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1889 "FunctionEnabled", wdtEnable,
1890 "TimeoutAction", wdtTimeOutAction))
1891 {
1892 return;
1893 }
1894 setWDTProperties(asyncResp, std::move(wdtEnable),
1895 std::move(wdtTimeOutAction));
1896 }
1897
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301898 if (bootProps)
1899 {
1900 std::optional<std::string> bootSource;
1901 std::optional<std::string> bootEnable;
1902
1903 if (!json_util::readJson(*bootProps, asyncResp->res,
1904 "BootSourceOverrideTarget", bootSource,
1905 "BootSourceOverrideEnabled", bootEnable))
1906 {
1907 return;
1908 }
1909 setBootProperties(asyncResp, std::move(bootSource),
1910 std::move(bootEnable));
1911 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001912
Ed Tanous9712f8a2018-09-21 13:38:49 -07001913 if (indicatorLed)
1914 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301915 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001916 }
George Liuc6a620f2020-04-10 17:18:11 +08001917
1918 if (powerRestorePolicy)
1919 {
1920 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
1921 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001922 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001923};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001924} // namespace redfish