blob: c17e13537d1fdf49c3b1ca1a4742b03fabe2bef8 [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/**
George Liuc6a620f2020-04-10 17:18:11 +0800920 * @brief Retrieves power restore policy over DBUS.
921 *
922 * @param[in] aResp Shared pointer for generating response message.
923 *
924 * @return None.
925 */
926void getPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp)
927{
928 BMCWEB_LOG_DEBUG << "Get power restore policy";
929
930 crow::connections::systemBus->async_method_call(
931 [aResp](const boost::system::error_code ec,
Patrick Williams19bd78d2020-05-13 17:38:24 -0500932 std::variant<std::string> &policy) {
George Liuc6a620f2020-04-10 17:18:11 +0800933 if (ec)
934 {
935 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
936 return;
937 }
938
939 const boost::container::flat_map<std::string, std::string>
940 policyMaps = {
941 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
942 "AlwaysOn",
943 "AlwaysOn"},
944 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
945 "AlwaysOff",
946 "AlwaysOff"},
947 {"xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
948 "LastState",
949 "LastState"}};
950
951 const std::string *policyPtr = std::get_if<std::string>(&policy);
952
953 if (!policyPtr)
954 {
955 messages::internalError(aResp->res);
956 return;
957 }
958
959 auto policyMapsIt = policyMaps.find(*policyPtr);
960 if (policyMapsIt == policyMaps.end())
961 {
962 messages::internalError(aResp->res);
963 return;
964 }
965
966 aResp->res.jsonValue["PowerRestorePolicy"] = policyMapsIt->second;
967 },
968 "xyz.openbmc_project.Settings",
969 "/xyz/openbmc_project/control/host0/power_restore_policy",
970 "org.freedesktop.DBus.Properties", "Get",
971 "xyz.openbmc_project.Control.Power.RestorePolicy",
972 "PowerRestorePolicy");
973}
974
975/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530976 * @brief Sets boot properties into DBUS object(s).
977 *
978 * @param[in] aResp Shared pointer for generating response message.
979 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
980 * @param[in] bootSource The boot source to set.
981 * @param[in] bootEnable The source override "enable" to set.
982 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700983 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530984 */
985static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
986 bool oneTimeEnabled,
987 std::optional<std::string> bootSource,
988 std::optional<std::string> bootEnable)
989{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700990 std::string bootSourceStr =
991 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
992 std::string bootModeStr =
993 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530994 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700995 bool useBootSource = true;
996
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530997 // Validate incoming parameters
998 if (bootEnable)
999 {
1000 if (*bootEnable == "Once")
1001 {
1002 oneTimeSetting = true;
1003 }
1004 else if (*bootEnable == "Continuous")
1005 {
1006 oneTimeSetting = false;
1007 }
1008 else if (*bootEnable == "Disabled")
1009 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001010 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301011 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001012 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301013 }
1014 else
1015 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301016 BMCWEB_LOG_DEBUG << "Unsupported value for "
1017 "BootSourceOverrideEnabled: "
1018 << *bootEnable;
1019 messages::propertyValueNotInList(aResp->res, *bootEnable,
1020 "BootSourceOverrideEnabled");
1021 return;
1022 }
1023 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301024
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001025 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301026 {
1027 // Source target specified
1028 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1029 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001030 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1031 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301032 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001033 BMCWEB_LOG_DEBUG
1034 << "Invalid property value for BootSourceOverrideTarget: "
1035 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301036 messages::propertyValueNotInList(aResp->res, *bootSource,
1037 "BootSourceTargetOverride");
1038 return;
1039 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001040 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301041
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001042 // Act on validated parameters
1043 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1044 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1045 const char *bootObj =
1046 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1047 : "/xyz/openbmc_project/control/host0/boot";
1048
1049 crow::connections::systemBus->async_method_call(
1050 [aResp](const boost::system::error_code ec) {
1051 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301052 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001053 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1054 messages::internalError(aResp->res);
1055 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301056 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001057 BMCWEB_LOG_DEBUG << "Boot source update done.";
1058 },
1059 "xyz.openbmc_project.Settings", bootObj,
1060 "org.freedesktop.DBus.Properties", "Set",
1061 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1062 std::variant<std::string>(bootSourceStr));
1063
1064 crow::connections::systemBus->async_method_call(
1065 [aResp](const boost::system::error_code ec) {
1066 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301067 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001068 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1069 messages::internalError(aResp->res);
1070 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301071 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001072 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1073 },
1074 "xyz.openbmc_project.Settings", bootObj,
1075 "org.freedesktop.DBus.Properties", "Set",
1076 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1077 std::variant<std::string>(bootModeStr));
1078
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301079 crow::connections::systemBus->async_method_call(
1080 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1081 if (ec)
1082 {
1083 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1084 messages::internalError(aResp->res);
1085 return;
1086 }
1087 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1088 },
1089 "xyz.openbmc_project.Settings",
1090 "/xyz/openbmc_project/control/host0/boot/one_time",
1091 "org.freedesktop.DBus.Properties", "Set",
1092 "xyz.openbmc_project.Object.Enable", "Enabled",
1093 std::variant<bool>(oneTimeSetting));
1094}
1095
1096/**
1097 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1098 * set boot source/boot mode properties.
1099 *
1100 * @param[in] aResp Shared pointer for generating response message.
1101 * @param[in] bootSource The boot source from incoming RF request.
1102 * @param[in] bootEnable The boot override enable from incoming RF request.
1103 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001104 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301105 */
1106static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1107 std::optional<std::string> bootSource,
1108 std::optional<std::string> bootEnable)
1109{
1110 BMCWEB_LOG_DEBUG << "Set boot information.";
1111
1112 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001113 [aResp, bootSource{std::move(bootSource)},
Patrick Williams19bd78d2020-05-13 17:38:24 -05001114 bootEnable{std::move(bootEnable)}](const boost::system::error_code ec,
1115 const std::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301116 if (ec)
1117 {
1118 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1119 messages::internalError(aResp->res);
1120 return;
1121 }
1122
1123 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1124
1125 if (!oneTimePtr)
1126 {
1127 messages::internalError(aResp->res);
1128 return;
1129 }
1130
1131 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1132
1133 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1134 std::move(bootEnable));
1135 },
1136 "xyz.openbmc_project.Settings",
1137 "/xyz/openbmc_project/control/host0/boot/one_time",
1138 "org.freedesktop.DBus.Properties", "Get",
1139 "xyz.openbmc_project.Object.Enable", "Enabled");
1140}
1141
George Liuc6a620f2020-04-10 17:18:11 +08001142/**
1143 * @brief Sets power restore policy properties.
1144 *
1145 * @param[in] aResp Shared pointer for generating response message.
1146 * @param[in] policy power restore policy properties from request.
1147 *
1148 * @return None.
1149 */
1150static void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
1151 std::optional<std::string> policy)
1152{
1153 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1154
1155 const boost::container::flat_map<std::string, std::string> policyMaps = {
1156 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1157 "AlwaysOn"},
1158 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1159 "AlwaysOff"},
1160 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1161 "LastState"}};
1162
1163 std::string powerRestorPolicy;
1164
1165 auto policyMapsIt = policyMaps.find(*policy);
1166 if (policyMapsIt == policyMaps.end())
1167 {
1168 messages::internalError(aResp->res);
1169 return;
1170 }
1171
1172 powerRestorPolicy = policyMapsIt->second;
1173
1174 crow::connections::systemBus->async_method_call(
1175 [aResp](const boost::system::error_code ec) {
1176 if (ec)
1177 {
1178 messages::internalError(aResp->res);
1179 return;
1180 }
1181 },
1182 "xyz.openbmc_project.Settings",
1183 "/xyz/openbmc_project/control/host0/power_restore_policy",
1184 "org.freedesktop.DBus.Properties", "Set",
1185 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1186 std::variant<std::string>(powerRestorPolicy));
1187}
1188
AppaRao Pulia6349912019-10-18 17:16:08 +05301189#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1190/**
1191 * @brief Retrieves provisioning status
1192 *
1193 * @param[in] aResp Shared pointer for completing asynchronous calls.
1194 *
1195 * @return None.
1196 */
1197void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1198{
1199 BMCWEB_LOG_DEBUG << "Get OEM information.";
1200 crow::connections::systemBus->async_method_call(
1201 [aResp](const boost::system::error_code ec,
1202 const std::vector<std::pair<std::string, VariantType>>
1203 &propertiesList) {
1204 if (ec)
1205 {
1206 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1207 messages::internalError(aResp->res);
1208 return;
1209 }
1210
1211 const bool *provState = nullptr;
1212 const bool *lockState = nullptr;
1213 for (const std::pair<std::string, VariantType> &property :
1214 propertiesList)
1215 {
1216 if (property.first == "UfmProvisioned")
1217 {
1218 provState = std::get_if<bool>(&property.second);
1219 }
1220 else if (property.first == "UfmLocked")
1221 {
1222 lockState = std::get_if<bool>(&property.second);
1223 }
1224 }
1225
1226 if ((provState == nullptr) || (lockState == nullptr))
1227 {
1228 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1229 messages::internalError(aResp->res);
1230 return;
1231 }
1232
1233 nlohmann::json &oemPFR =
1234 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1235 if (*provState == true)
1236 {
1237 if (*lockState == true)
1238 {
1239 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1240 }
1241 else
1242 {
1243 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1244 }
1245 }
1246 else
1247 {
1248 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1249 }
1250 },
1251 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1252 "org.freedesktop.DBus.Properties", "GetAll",
1253 "xyz.openbmc_project.PFR.Attributes");
1254}
1255#endif
1256
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301257/**
Yong Li51709ff2019-09-30 14:13:04 +08001258 * @brief Translates watchdog timeout action DBUS property value to redfish.
1259 *
1260 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1261 *
1262 * @return Returns as a string, the timeout action in Redfish terms. If
1263 * translation cannot be done, returns an empty string.
1264 */
1265static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1266{
1267 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1268 {
1269 return "None";
1270 }
1271 else if (dbusAction ==
1272 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1273 {
1274 return "ResetSystem";
1275 }
1276 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1277 {
1278 return "PowerDown";
1279 }
1280 else if (dbusAction ==
1281 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1282 {
1283 return "PowerCycle";
1284 }
1285
1286 return "";
1287}
1288
1289/**
Yong Lic45f0082019-10-10 14:19:01 +08001290 *@brief Translates timeout action from Redfish to DBUS property value.
1291 *
1292 *@param[in] rfAction The timeout action in Redfish.
1293 *
1294 *@return Returns as a string, the time_out action as expected by DBUS.
1295 *If translation cannot be done, returns an empty string.
1296 */
1297
1298static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1299{
1300 if (rfAction == "None")
1301 {
1302 return "xyz.openbmc_project.State.Watchdog.Action.None";
1303 }
1304 else if (rfAction == "PowerCycle")
1305 {
1306 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1307 }
1308 else if (rfAction == "PowerDown")
1309 {
1310 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1311 }
1312 else if (rfAction == "ResetSystem")
1313 {
1314 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1315 }
1316
1317 return "";
1318}
1319
1320/**
Yong Li51709ff2019-09-30 14:13:04 +08001321 * @brief Retrieves host watchdog timer properties over DBUS
1322 *
1323 * @param[in] aResp Shared pointer for completing asynchronous calls.
1324 *
1325 * @return None.
1326 */
1327void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1328{
1329 BMCWEB_LOG_DEBUG << "Get host watchodg";
1330 crow::connections::systemBus->async_method_call(
1331 [aResp](const boost::system::error_code ec,
1332 PropertiesType &properties) {
1333 if (ec)
1334 {
1335 // watchdog service is stopped
1336 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1337 return;
1338 }
1339
1340 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1341
1342 nlohmann::json &hostWatchdogTimer =
1343 aResp->res.jsonValue["HostWatchdogTimer"];
1344
1345 // watchdog service is running/enabled
1346 hostWatchdogTimer["Status"]["State"] = "Enabled";
1347
1348 for (const auto &property : properties)
1349 {
1350 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1351 if (property.first == "Enabled")
1352 {
1353 const bool *state = std::get_if<bool>(&property.second);
1354
1355 if (!state)
1356 {
1357 messages::internalError(aResp->res);
1358 continue;
1359 }
1360
1361 hostWatchdogTimer["FunctionEnabled"] = *state;
1362 }
1363 else if (property.first == "ExpireAction")
1364 {
1365 const std::string *s =
1366 std::get_if<std::string>(&property.second);
1367 if (!s)
1368 {
1369 messages::internalError(aResp->res);
1370 continue;
1371 }
1372
1373 std::string action = dbusToRfWatchdogAction(*s);
1374 if (action.empty())
1375 {
1376 messages::internalError(aResp->res);
1377 continue;
1378 }
1379 hostWatchdogTimer["TimeoutAction"] = action;
1380 }
1381 }
1382 },
1383 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1384 "org.freedesktop.DBus.Properties", "GetAll",
1385 "xyz.openbmc_project.State.Watchdog");
1386}
1387
1388/**
Yong Lic45f0082019-10-10 14:19:01 +08001389 * @brief Sets Host WatchDog Timer properties.
1390 *
1391 * @param[in] aResp Shared pointer for generating response message.
1392 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1393 * RF request.
1394 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1395 *
1396 * @return None.
1397 */
1398static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1399 const std::optional<bool> wdtEnable,
1400 const std::optional<std::string> &wdtTimeOutAction)
1401{
1402 BMCWEB_LOG_DEBUG << "Set host watchdog";
1403
1404 if (wdtTimeOutAction)
1405 {
1406 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1407 // check if TimeOut Action is Valid
1408 if (wdtTimeOutActStr.empty())
1409 {
1410 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1411 << *wdtTimeOutAction;
1412 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1413 "TimeoutAction");
1414 return;
1415 }
1416
1417 crow::connections::systemBus->async_method_call(
1418 [aResp](const boost::system::error_code ec) {
1419 if (ec)
1420 {
1421 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1422 messages::internalError(aResp->res);
1423 return;
1424 }
1425 },
1426 "xyz.openbmc_project.Watchdog",
1427 "/xyz/openbmc_project/watchdog/host0",
1428 "org.freedesktop.DBus.Properties", "Set",
1429 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1430 std::variant<std::string>(wdtTimeOutActStr));
1431 }
1432
1433 if (wdtEnable)
1434 {
1435 crow::connections::systemBus->async_method_call(
1436 [aResp](const boost::system::error_code ec) {
1437 if (ec)
1438 {
1439 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1440 messages::internalError(aResp->res);
1441 return;
1442 }
1443 },
1444 "xyz.openbmc_project.Watchdog",
1445 "/xyz/openbmc_project/watchdog/host0",
1446 "org.freedesktop.DBus.Properties", "Set",
1447 "xyz.openbmc_project.State.Watchdog", "Enabled",
1448 std::variant<bool>(*wdtEnable));
1449 }
1450}
1451
1452/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001453 * SystemsCollection derived class for delivering ComputerSystems Collection
1454 * Schema
1455 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001456class SystemsCollection : public Node
1457{
1458 public:
1459 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1460 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001461 entityPrivileges = {
1462 {boost::beast::http::verb::get, {{"Login"}}},
1463 {boost::beast::http::verb::head, {{"Login"}}},
1464 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1465 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1466 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1467 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1468 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001469
Ed Tanous1abe55e2018-09-05 08:30:59 -07001470 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001471 void doGet(crow::Response &res, const crow::Request &req,
1472 const std::vector<std::string> &params) override
1473 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001474 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001475 res.jsonValue["@odata.type"] =
1476 "#ComputerSystemCollection.ComputerSystemCollection";
1477 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001478 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001479
1480 crow::connections::systemBus->async_method_call(
1481 [asyncResp](const boost::system::error_code ec,
1482 const std::variant<std::string> &hostName) {
1483 nlohmann::json &iface_array =
1484 asyncResp->res.jsonValue["Members"];
1485 iface_array = nlohmann::json::array();
1486 auto &count = asyncResp->res.jsonValue["Members@odata.count"];
1487 count = 0;
1488 if (ec)
1489 {
1490 iface_array.push_back(
1491 {{"@odata.id", "/redfish/v1/Systems/system"}});
1492 count = iface_array.size();
1493 return;
1494 }
1495 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1496 iface_array.push_back(
1497 {{"@odata.id", "/redfish/v1/Systems/system"}});
1498 iface_array.push_back(
1499 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1500 count = iface_array.size();
1501 },
1502 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/vmi",
1503 "org.freedesktop.DBus.Properties", "Get",
1504 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001505 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001506};
1507
1508/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001509 * SystemActionsReset class supports handle POST method for Reset action.
1510 * The class retrieves and sends data directly to D-Bus.
1511 */
1512class SystemActionsReset : public Node
1513{
1514 public:
1515 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001516 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001517 {
1518 entityPrivileges = {
1519 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1520 }
1521
1522 private:
1523 /**
1524 * Function handles POST method request.
1525 * Analyzes POST body message before sends Reset request data to D-Bus.
1526 */
1527 void doPost(crow::Response &res, const crow::Request &req,
1528 const std::vector<std::string> &params) override
1529 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001530 auto asyncResp = std::make_shared<AsyncResp>(res);
1531
1532 std::string resetType;
1533 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001534 {
1535 return;
1536 }
1537
Jason M. Billsd22c8392019-06-03 13:59:03 -07001538 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001539 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001540 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001541 if (resetType == "On")
1542 {
1543 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001544 hostCommand = true;
1545 }
1546 else if (resetType == "ForceOff")
1547 {
1548 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1549 hostCommand = false;
1550 }
1551 else if (resetType == "ForceOn")
1552 {
1553 command = "xyz.openbmc_project.State.Host.Transition.On";
1554 hostCommand = true;
1555 }
1556 else if (resetType == "ForceRestart")
1557 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001558 command =
1559 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1560 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001561 }
1562 else if (resetType == "GracefulShutdown")
1563 {
1564 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001565 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001566 }
1567 else if (resetType == "GracefulRestart")
1568 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001569 command =
1570 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001571 hostCommand = true;
1572 }
1573 else if (resetType == "PowerCycle")
1574 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001575 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1576 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001577 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001578 else if (resetType == "Nmi")
1579 {
1580 doNMI(asyncResp);
1581 return;
1582 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001583 else
1584 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001585 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001586 return;
1587 }
1588
Jason M. Billsd22c8392019-06-03 13:59:03 -07001589 if (hostCommand)
1590 {
1591 crow::connections::systemBus->async_method_call(
1592 [asyncResp, resetType](const boost::system::error_code ec) {
1593 if (ec)
1594 {
1595 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1596 if (ec.value() == boost::asio::error::invalid_argument)
1597 {
1598 messages::actionParameterNotSupported(
1599 asyncResp->res, resetType, "Reset");
1600 }
1601 else
1602 {
1603 messages::internalError(asyncResp->res);
1604 }
1605 return;
1606 }
1607 messages::success(asyncResp->res);
1608 },
1609 "xyz.openbmc_project.State.Host",
1610 "/xyz/openbmc_project/state/host0",
1611 "org.freedesktop.DBus.Properties", "Set",
1612 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1613 std::variant<std::string>{command});
1614 }
1615 else
1616 {
1617 crow::connections::systemBus->async_method_call(
1618 [asyncResp, resetType](const boost::system::error_code ec) {
1619 if (ec)
1620 {
1621 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1622 if (ec.value() == boost::asio::error::invalid_argument)
1623 {
1624 messages::actionParameterNotSupported(
1625 asyncResp->res, resetType, "Reset");
1626 }
1627 else
1628 {
1629 messages::internalError(asyncResp->res);
1630 }
1631 return;
1632 }
1633 messages::success(asyncResp->res);
1634 },
1635 "xyz.openbmc_project.State.Chassis",
1636 "/xyz/openbmc_project/state/chassis0",
1637 "org.freedesktop.DBus.Properties", "Set",
1638 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1639 std::variant<std::string>{command});
1640 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001641 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001642 /**
1643 * Function transceives data with dbus directly.
1644 */
1645 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1646 {
1647 constexpr char const *serviceName =
1648 "xyz.openbmc_project.Control.Host.NMI";
1649 constexpr char const *objectPath =
1650 "/xyz/openbmc_project/control/host0/nmi";
1651 constexpr char const *interfaceName =
1652 "xyz.openbmc_project.Control.Host.NMI";
1653 constexpr char const *method = "NMI";
1654
1655 crow::connections::systemBus->async_method_call(
1656 [asyncResp](const boost::system::error_code ec) {
1657 if (ec)
1658 {
1659 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1660 messages::internalError(asyncResp->res);
1661 return;
1662 }
1663 messages::success(asyncResp->res);
1664 },
1665 serviceName, objectPath, interfaceName, method);
1666 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001667};
1668
1669/**
Ed Tanous66173382018-08-15 18:20:59 -07001670 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001671 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001672class Systems : public Node
1673{
1674 public:
1675 /*
1676 * Default Constructor
1677 */
Ed Tanous029573d2019-02-01 10:57:49 -08001678 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001679 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001680 entityPrivileges = {
1681 {boost::beast::http::verb::get, {{"Login"}}},
1682 {boost::beast::http::verb::head, {{"Login"}}},
1683 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1684 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1685 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1686 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001687 }
1688
Ed Tanous1abe55e2018-09-05 08:30:59 -07001689 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001690 /**
1691 * Functions triggers appropriate requests on DBus
1692 */
1693 void doGet(crow::Response &res, const crow::Request &req,
1694 const std::vector<std::string> &params) override
1695 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301696 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001697 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001698 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001699 res.jsonValue["SystemType"] = "Physical";
1700 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001701 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1702 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001703 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001704 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001705 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001706
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001707 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001708 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001709 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001710 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001711 res.jsonValue["Storage"] = {
1712 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001713
Ed Tanouscc340dd2018-08-29 13:43:38 -07001714 // TODO Need to support ForceRestart.
1715 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1716 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001717 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001718 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001719 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001720 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001721
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001722 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001723 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001724
Carol Wangd82a3ac2019-11-21 13:56:38 +08001725 res.jsonValue["Bios"] = {
1726 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1727
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001728 res.jsonValue["Links"]["ManagedBy"] = {
1729 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1730
1731 res.jsonValue["Status"] = {
1732 {"Health", "OK"},
1733 {"State", "Enabled"},
1734 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001735 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001736
James Feiste284a7c2019-11-20 16:20:23 -08001737 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001738 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001739 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001740 "xyz.openbmc_project.Inventory.Item.Drive",
1741 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001742
1743 auto health = std::make_shared<HealthPopulate>(asyncResp);
1744 crow::connections::systemBus->async_method_call(
1745 [health](const boost::system::error_code ec,
1746 std::vector<std::string> &resp) {
1747 if (ec)
1748 {
1749 // no inventory
1750 return;
1751 }
1752
1753 health->inventory = std::move(resp);
1754 },
1755 "xyz.openbmc_project.ObjectMapper",
1756 "/xyz/openbmc_project/object_mapper",
1757 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1758 int32_t(0), inventoryForSystems);
1759
1760 health->populate();
1761
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001762 getMainChassisId(asyncResp, [](const std::string &chassisId,
1763 std::shared_ptr<AsyncResp> aRsp) {
1764 aRsp->res.jsonValue["Links"]["Chassis"] = {
1765 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1766 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301767
1768 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001769 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001770 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301771 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001772 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001773 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001774 getPowerRestorePolicy(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301775#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1776 getProvisioningStatus(asyncResp);
1777#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001778 }
1779
Ed Tanous1abe55e2018-09-05 08:30:59 -07001780 void doPatch(crow::Response &res, const crow::Request &req,
1781 const std::vector<std::string> &params) override
1782 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301783 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301784 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001785 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001786 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001787 auto asyncResp = std::make_shared<AsyncResp>(res);
1788
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001789 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001790 bootProps, "WatchdogTimer", wdtTimerProps,
1791 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001792 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001793 return;
1794 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301795
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001796 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001797
1798 if (wdtTimerProps)
1799 {
1800 std::optional<bool> wdtEnable;
1801 std::optional<std::string> wdtTimeOutAction;
1802
1803 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1804 "FunctionEnabled", wdtEnable,
1805 "TimeoutAction", wdtTimeOutAction))
1806 {
1807 return;
1808 }
1809 setWDTProperties(asyncResp, std::move(wdtEnable),
1810 std::move(wdtTimeOutAction));
1811 }
1812
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301813 if (bootProps)
1814 {
1815 std::optional<std::string> bootSource;
1816 std::optional<std::string> bootEnable;
1817
1818 if (!json_util::readJson(*bootProps, asyncResp->res,
1819 "BootSourceOverrideTarget", bootSource,
1820 "BootSourceOverrideEnabled", bootEnable))
1821 {
1822 return;
1823 }
1824 setBootProperties(asyncResp, std::move(bootSource),
1825 std::move(bootEnable));
1826 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001827
Ed Tanous9712f8a2018-09-21 13:38:49 -07001828 if (indicatorLed)
1829 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301830 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001831 }
George Liuc6a620f2020-04-10 17:18:11 +08001832
1833 if (powerRestorePolicy)
1834 {
1835 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
1836 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001837 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001838};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001839} // namespace redfish