blob: a4c4f5bd6128ac9b30db07e2ea4846c1fc874c44 [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,
896 const sdbusplus::message::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,
932 sdbusplus::message::variant<std::string> &policy) {
933 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)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301114 bootEnable{std::move(bootEnable)}](
1115 const boost::system::error_code ec,
1116 const sdbusplus::message::variant<bool> &oneTime) {
1117 if (ec)
1118 {
1119 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1120 messages::internalError(aResp->res);
1121 return;
1122 }
1123
1124 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1125
1126 if (!oneTimePtr)
1127 {
1128 messages::internalError(aResp->res);
1129 return;
1130 }
1131
1132 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1133
1134 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1135 std::move(bootEnable));
1136 },
1137 "xyz.openbmc_project.Settings",
1138 "/xyz/openbmc_project/control/host0/boot/one_time",
1139 "org.freedesktop.DBus.Properties", "Get",
1140 "xyz.openbmc_project.Object.Enable", "Enabled");
1141}
1142
George Liuc6a620f2020-04-10 17:18:11 +08001143/**
1144 * @brief Sets power restore policy properties.
1145 *
1146 * @param[in] aResp Shared pointer for generating response message.
1147 * @param[in] policy power restore policy properties from request.
1148 *
1149 * @return None.
1150 */
1151static void setPowerRestorePolicy(std::shared_ptr<AsyncResp> aResp,
1152 std::optional<std::string> policy)
1153{
1154 BMCWEB_LOG_DEBUG << "Set power restore policy.";
1155
1156 const boost::container::flat_map<std::string, std::string> policyMaps = {
1157 {"AlwaysOn", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1158 "AlwaysOn"},
1159 {"AlwaysOff", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1160 "AlwaysOff"},
1161 {"LastState", "xyz.openbmc_project.Control.Power.RestorePolicy.Policy."
1162 "LastState"}};
1163
1164 std::string powerRestorPolicy;
1165
1166 auto policyMapsIt = policyMaps.find(*policy);
1167 if (policyMapsIt == policyMaps.end())
1168 {
1169 messages::internalError(aResp->res);
1170 return;
1171 }
1172
1173 powerRestorPolicy = policyMapsIt->second;
1174
1175 crow::connections::systemBus->async_method_call(
1176 [aResp](const boost::system::error_code ec) {
1177 if (ec)
1178 {
1179 messages::internalError(aResp->res);
1180 return;
1181 }
1182 },
1183 "xyz.openbmc_project.Settings",
1184 "/xyz/openbmc_project/control/host0/power_restore_policy",
1185 "org.freedesktop.DBus.Properties", "Set",
1186 "xyz.openbmc_project.Control.Power.RestorePolicy", "PowerRestorePolicy",
1187 std::variant<std::string>(powerRestorPolicy));
1188}
1189
AppaRao Pulia6349912019-10-18 17:16:08 +05301190#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1191/**
1192 * @brief Retrieves provisioning status
1193 *
1194 * @param[in] aResp Shared pointer for completing asynchronous calls.
1195 *
1196 * @return None.
1197 */
1198void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1199{
1200 BMCWEB_LOG_DEBUG << "Get OEM information.";
1201 crow::connections::systemBus->async_method_call(
1202 [aResp](const boost::system::error_code ec,
1203 const std::vector<std::pair<std::string, VariantType>>
1204 &propertiesList) {
1205 if (ec)
1206 {
1207 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1208 messages::internalError(aResp->res);
1209 return;
1210 }
1211
1212 const bool *provState = nullptr;
1213 const bool *lockState = nullptr;
1214 for (const std::pair<std::string, VariantType> &property :
1215 propertiesList)
1216 {
1217 if (property.first == "UfmProvisioned")
1218 {
1219 provState = std::get_if<bool>(&property.second);
1220 }
1221 else if (property.first == "UfmLocked")
1222 {
1223 lockState = std::get_if<bool>(&property.second);
1224 }
1225 }
1226
1227 if ((provState == nullptr) || (lockState == nullptr))
1228 {
1229 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1230 messages::internalError(aResp->res);
1231 return;
1232 }
1233
1234 nlohmann::json &oemPFR =
1235 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1236 if (*provState == true)
1237 {
1238 if (*lockState == true)
1239 {
1240 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1241 }
1242 else
1243 {
1244 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1245 }
1246 }
1247 else
1248 {
1249 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1250 }
1251 },
1252 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1253 "org.freedesktop.DBus.Properties", "GetAll",
1254 "xyz.openbmc_project.PFR.Attributes");
1255}
1256#endif
1257
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301258/**
Yong Li51709ff2019-09-30 14:13:04 +08001259 * @brief Translates watchdog timeout action DBUS property value to redfish.
1260 *
1261 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1262 *
1263 * @return Returns as a string, the timeout action in Redfish terms. If
1264 * translation cannot be done, returns an empty string.
1265 */
1266static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1267{
1268 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1269 {
1270 return "None";
1271 }
1272 else if (dbusAction ==
1273 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1274 {
1275 return "ResetSystem";
1276 }
1277 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1278 {
1279 return "PowerDown";
1280 }
1281 else if (dbusAction ==
1282 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1283 {
1284 return "PowerCycle";
1285 }
1286
1287 return "";
1288}
1289
1290/**
Yong Lic45f0082019-10-10 14:19:01 +08001291 *@brief Translates timeout action from Redfish to DBUS property value.
1292 *
1293 *@param[in] rfAction The timeout action in Redfish.
1294 *
1295 *@return Returns as a string, the time_out action as expected by DBUS.
1296 *If translation cannot be done, returns an empty string.
1297 */
1298
1299static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1300{
1301 if (rfAction == "None")
1302 {
1303 return "xyz.openbmc_project.State.Watchdog.Action.None";
1304 }
1305 else if (rfAction == "PowerCycle")
1306 {
1307 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1308 }
1309 else if (rfAction == "PowerDown")
1310 {
1311 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1312 }
1313 else if (rfAction == "ResetSystem")
1314 {
1315 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1316 }
1317
1318 return "";
1319}
1320
1321/**
Yong Li51709ff2019-09-30 14:13:04 +08001322 * @brief Retrieves host watchdog timer properties over DBUS
1323 *
1324 * @param[in] aResp Shared pointer for completing asynchronous calls.
1325 *
1326 * @return None.
1327 */
1328void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1329{
1330 BMCWEB_LOG_DEBUG << "Get host watchodg";
1331 crow::connections::systemBus->async_method_call(
1332 [aResp](const boost::system::error_code ec,
1333 PropertiesType &properties) {
1334 if (ec)
1335 {
1336 // watchdog service is stopped
1337 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1338 return;
1339 }
1340
1341 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1342
1343 nlohmann::json &hostWatchdogTimer =
1344 aResp->res.jsonValue["HostWatchdogTimer"];
1345
1346 // watchdog service is running/enabled
1347 hostWatchdogTimer["Status"]["State"] = "Enabled";
1348
1349 for (const auto &property : properties)
1350 {
1351 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1352 if (property.first == "Enabled")
1353 {
1354 const bool *state = std::get_if<bool>(&property.second);
1355
1356 if (!state)
1357 {
1358 messages::internalError(aResp->res);
1359 continue;
1360 }
1361
1362 hostWatchdogTimer["FunctionEnabled"] = *state;
1363 }
1364 else if (property.first == "ExpireAction")
1365 {
1366 const std::string *s =
1367 std::get_if<std::string>(&property.second);
1368 if (!s)
1369 {
1370 messages::internalError(aResp->res);
1371 continue;
1372 }
1373
1374 std::string action = dbusToRfWatchdogAction(*s);
1375 if (action.empty())
1376 {
1377 messages::internalError(aResp->res);
1378 continue;
1379 }
1380 hostWatchdogTimer["TimeoutAction"] = action;
1381 }
1382 }
1383 },
1384 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1385 "org.freedesktop.DBus.Properties", "GetAll",
1386 "xyz.openbmc_project.State.Watchdog");
1387}
1388
1389/**
Yong Lic45f0082019-10-10 14:19:01 +08001390 * @brief Sets Host WatchDog Timer properties.
1391 *
1392 * @param[in] aResp Shared pointer for generating response message.
1393 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1394 * RF request.
1395 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1396 *
1397 * @return None.
1398 */
1399static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1400 const std::optional<bool> wdtEnable,
1401 const std::optional<std::string> &wdtTimeOutAction)
1402{
1403 BMCWEB_LOG_DEBUG << "Set host watchdog";
1404
1405 if (wdtTimeOutAction)
1406 {
1407 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1408 // check if TimeOut Action is Valid
1409 if (wdtTimeOutActStr.empty())
1410 {
1411 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1412 << *wdtTimeOutAction;
1413 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1414 "TimeoutAction");
1415 return;
1416 }
1417
1418 crow::connections::systemBus->async_method_call(
1419 [aResp](const boost::system::error_code ec) {
1420 if (ec)
1421 {
1422 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1423 messages::internalError(aResp->res);
1424 return;
1425 }
1426 },
1427 "xyz.openbmc_project.Watchdog",
1428 "/xyz/openbmc_project/watchdog/host0",
1429 "org.freedesktop.DBus.Properties", "Set",
1430 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1431 std::variant<std::string>(wdtTimeOutActStr));
1432 }
1433
1434 if (wdtEnable)
1435 {
1436 crow::connections::systemBus->async_method_call(
1437 [aResp](const boost::system::error_code ec) {
1438 if (ec)
1439 {
1440 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1441 messages::internalError(aResp->res);
1442 return;
1443 }
1444 },
1445 "xyz.openbmc_project.Watchdog",
1446 "/xyz/openbmc_project/watchdog/host0",
1447 "org.freedesktop.DBus.Properties", "Set",
1448 "xyz.openbmc_project.State.Watchdog", "Enabled",
1449 std::variant<bool>(*wdtEnable));
1450 }
1451}
1452
1453/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001454 * SystemsCollection derived class for delivering ComputerSystems Collection
1455 * Schema
1456 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001457class SystemsCollection : public Node
1458{
1459 public:
1460 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1461 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001462 entityPrivileges = {
1463 {boost::beast::http::verb::get, {{"Login"}}},
1464 {boost::beast::http::verb::head, {{"Login"}}},
1465 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1466 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1467 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1468 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1469 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001470
Ed Tanous1abe55e2018-09-05 08:30:59 -07001471 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001472 void doGet(crow::Response &res, const crow::Request &req,
1473 const std::vector<std::string> &params) override
1474 {
Sunitha Harish462023a2020-02-19 08:34:59 -06001475 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -08001476 res.jsonValue["@odata.type"] =
1477 "#ComputerSystemCollection.ComputerSystemCollection";
1478 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
Ed Tanous0f74e642018-11-12 15:17:05 -08001479 res.jsonValue["Name"] = "Computer System Collection";
Sunitha Harish462023a2020-02-19 08:34:59 -06001480
1481 crow::connections::systemBus->async_method_call(
1482 [asyncResp](const boost::system::error_code ec,
1483 const std::variant<std::string> &hostName) {
1484 nlohmann::json &iface_array =
1485 asyncResp->res.jsonValue["Members"];
1486 iface_array = nlohmann::json::array();
1487 auto &count = asyncResp->res.jsonValue["Members@odata.count"];
1488 count = 0;
1489 if (ec)
1490 {
1491 iface_array.push_back(
1492 {{"@odata.id", "/redfish/v1/Systems/system"}});
1493 count = iface_array.size();
1494 return;
1495 }
1496 BMCWEB_LOG_DEBUG << "Hypervisor is available";
1497 iface_array.push_back(
1498 {{"@odata.id", "/redfish/v1/Systems/system"}});
1499 iface_array.push_back(
1500 {{"@odata.id", "/redfish/v1/Systems/hypervisor"}});
1501 count = iface_array.size();
1502 },
1503 "xyz.openbmc_project.Settings", "/xyz/openbmc_project/network/vmi",
1504 "org.freedesktop.DBus.Properties", "Get",
1505 "xyz.openbmc_project.Network.SystemConfiguration", "HostName");
Ed Tanous1abe55e2018-09-05 08:30:59 -07001506 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001507};
1508
1509/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001510 * SystemActionsReset class supports handle POST method for Reset action.
1511 * The class retrieves and sends data directly to D-Bus.
1512 */
1513class SystemActionsReset : public Node
1514{
1515 public:
1516 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001517 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001518 {
1519 entityPrivileges = {
1520 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1521 }
1522
1523 private:
1524 /**
1525 * Function handles POST method request.
1526 * Analyzes POST body message before sends Reset request data to D-Bus.
1527 */
1528 void doPost(crow::Response &res, const crow::Request &req,
1529 const std::vector<std::string> &params) override
1530 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001531 auto asyncResp = std::make_shared<AsyncResp>(res);
1532
1533 std::string resetType;
1534 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001535 {
1536 return;
1537 }
1538
Jason M. Billsd22c8392019-06-03 13:59:03 -07001539 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001540 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001541 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001542 if (resetType == "On")
1543 {
1544 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001545 hostCommand = true;
1546 }
1547 else if (resetType == "ForceOff")
1548 {
1549 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1550 hostCommand = false;
1551 }
1552 else if (resetType == "ForceOn")
1553 {
1554 command = "xyz.openbmc_project.State.Host.Transition.On";
1555 hostCommand = true;
1556 }
1557 else if (resetType == "ForceRestart")
1558 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001559 command =
1560 "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot";
1561 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001562 }
1563 else if (resetType == "GracefulShutdown")
1564 {
1565 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001566 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001567 }
1568 else if (resetType == "GracefulRestart")
1569 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001570 command =
1571 "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001572 hostCommand = true;
1573 }
1574 else if (resetType == "PowerCycle")
1575 {
Jason M. Bills86a08512020-02-04 13:15:49 -08001576 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1577 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001578 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001579 else if (resetType == "Nmi")
1580 {
1581 doNMI(asyncResp);
1582 return;
1583 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001584 else
1585 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001586 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001587 return;
1588 }
1589
Jason M. Billsd22c8392019-06-03 13:59:03 -07001590 if (hostCommand)
1591 {
1592 crow::connections::systemBus->async_method_call(
1593 [asyncResp, resetType](const boost::system::error_code ec) {
1594 if (ec)
1595 {
1596 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1597 if (ec.value() == boost::asio::error::invalid_argument)
1598 {
1599 messages::actionParameterNotSupported(
1600 asyncResp->res, resetType, "Reset");
1601 }
1602 else
1603 {
1604 messages::internalError(asyncResp->res);
1605 }
1606 return;
1607 }
1608 messages::success(asyncResp->res);
1609 },
1610 "xyz.openbmc_project.State.Host",
1611 "/xyz/openbmc_project/state/host0",
1612 "org.freedesktop.DBus.Properties", "Set",
1613 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1614 std::variant<std::string>{command});
1615 }
1616 else
1617 {
1618 crow::connections::systemBus->async_method_call(
1619 [asyncResp, resetType](const boost::system::error_code ec) {
1620 if (ec)
1621 {
1622 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1623 if (ec.value() == boost::asio::error::invalid_argument)
1624 {
1625 messages::actionParameterNotSupported(
1626 asyncResp->res, resetType, "Reset");
1627 }
1628 else
1629 {
1630 messages::internalError(asyncResp->res);
1631 }
1632 return;
1633 }
1634 messages::success(asyncResp->res);
1635 },
1636 "xyz.openbmc_project.State.Chassis",
1637 "/xyz/openbmc_project/state/chassis0",
1638 "org.freedesktop.DBus.Properties", "Set",
1639 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1640 std::variant<std::string>{command});
1641 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001642 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001643 /**
1644 * Function transceives data with dbus directly.
1645 */
1646 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1647 {
1648 constexpr char const *serviceName =
1649 "xyz.openbmc_project.Control.Host.NMI";
1650 constexpr char const *objectPath =
1651 "/xyz/openbmc_project/control/host0/nmi";
1652 constexpr char const *interfaceName =
1653 "xyz.openbmc_project.Control.Host.NMI";
1654 constexpr char const *method = "NMI";
1655
1656 crow::connections::systemBus->async_method_call(
1657 [asyncResp](const boost::system::error_code ec) {
1658 if (ec)
1659 {
1660 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1661 messages::internalError(asyncResp->res);
1662 return;
1663 }
1664 messages::success(asyncResp->res);
1665 },
1666 serviceName, objectPath, interfaceName, method);
1667 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001668};
1669
1670/**
Ed Tanous66173382018-08-15 18:20:59 -07001671 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001672 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001673class Systems : public Node
1674{
1675 public:
1676 /*
1677 * Default Constructor
1678 */
Ed Tanous029573d2019-02-01 10:57:49 -08001679 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001680 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001681 entityPrivileges = {
1682 {boost::beast::http::verb::get, {{"Login"}}},
1683 {boost::beast::http::verb::head, {{"Login"}}},
1684 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1685 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1686 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1687 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001688 }
1689
Ed Tanous1abe55e2018-09-05 08:30:59 -07001690 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001691 /**
1692 * Functions triggers appropriate requests on DBus
1693 */
1694 void doGet(crow::Response &res, const crow::Request &req,
1695 const std::vector<std::string> &params) override
1696 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301697 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Gunnar Mills450a25c2020-04-14 21:34:07 -05001698 res.jsonValue["Name"] = "system";
Ed Tanous029573d2019-02-01 10:57:49 -08001699 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001700 res.jsonValue["SystemType"] = "Physical";
1701 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001702 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1703 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
Cheng C Yang5fd7ba62019-11-28 15:58:08 +08001704 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = uint64_t(0);
Ed Tanous0f74e642018-11-12 15:17:05 -08001705 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001706 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001707
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001708 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001709 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001710 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001711 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001712 res.jsonValue["Storage"] = {
1713 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001714
Ed Tanouscc340dd2018-08-29 13:43:38 -07001715 // TODO Need to support ForceRestart.
1716 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1717 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001718 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001719 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001720 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001721 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001722
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001723 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001724 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001725
Carol Wangd82a3ac2019-11-21 13:56:38 +08001726 res.jsonValue["Bios"] = {
1727 {"@odata.id", "/redfish/v1/Systems/system/Bios"}};
1728
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001729 res.jsonValue["Links"]["ManagedBy"] = {
1730 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1731
1732 res.jsonValue["Status"] = {
1733 {"Health", "OK"},
1734 {"State", "Enabled"},
1735 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001736 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001737
James Feiste284a7c2019-11-20 16:20:23 -08001738 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001739 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001740 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001741 "xyz.openbmc_project.Inventory.Item.Drive",
1742 "xyz.openbmc_project.Inventory.Item.StorageController"};
James Feistb49ac872019-05-21 15:12:01 -07001743
1744 auto health = std::make_shared<HealthPopulate>(asyncResp);
1745 crow::connections::systemBus->async_method_call(
1746 [health](const boost::system::error_code ec,
1747 std::vector<std::string> &resp) {
1748 if (ec)
1749 {
1750 // no inventory
1751 return;
1752 }
1753
1754 health->inventory = std::move(resp);
1755 },
1756 "xyz.openbmc_project.ObjectMapper",
1757 "/xyz/openbmc_project/object_mapper",
1758 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1759 int32_t(0), inventoryForSystems);
1760
1761 health->populate();
1762
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001763 getMainChassisId(asyncResp, [](const std::string &chassisId,
1764 std::shared_ptr<AsyncResp> aRsp) {
1765 aRsp->res.jsonValue["Links"]["Chassis"] = {
1766 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1767 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301768
1769 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001770 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001771 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301772 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001773 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001774 getHostWatchdogTimer(asyncResp);
George Liuc6a620f2020-04-10 17:18:11 +08001775 getPowerRestorePolicy(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301776#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1777 getProvisioningStatus(asyncResp);
1778#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001779 }
1780
Ed Tanous1abe55e2018-09-05 08:30:59 -07001781 void doPatch(crow::Response &res, const crow::Request &req,
1782 const std::vector<std::string> &params) override
1783 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301784 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301785 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001786 std::optional<nlohmann::json> wdtTimerProps;
George Liuc6a620f2020-04-10 17:18:11 +08001787 std::optional<std::string> powerRestorePolicy;
Santosh Puranik41352c22019-07-03 05:35:49 -05001788 auto asyncResp = std::make_shared<AsyncResp>(res);
1789
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001790 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
George Liuc6a620f2020-04-10 17:18:11 +08001791 bootProps, "WatchdogTimer", wdtTimerProps,
1792 "PowerRestorePolicy", powerRestorePolicy))
Ed Tanous66173382018-08-15 18:20:59 -07001793 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001794 return;
1795 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301796
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001797 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001798
1799 if (wdtTimerProps)
1800 {
1801 std::optional<bool> wdtEnable;
1802 std::optional<std::string> wdtTimeOutAction;
1803
1804 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1805 "FunctionEnabled", wdtEnable,
1806 "TimeoutAction", wdtTimeOutAction))
1807 {
1808 return;
1809 }
1810 setWDTProperties(asyncResp, std::move(wdtEnable),
1811 std::move(wdtTimeOutAction));
1812 }
1813
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301814 if (bootProps)
1815 {
1816 std::optional<std::string> bootSource;
1817 std::optional<std::string> bootEnable;
1818
1819 if (!json_util::readJson(*bootProps, asyncResp->res,
1820 "BootSourceOverrideTarget", bootSource,
1821 "BootSourceOverrideEnabled", bootEnable))
1822 {
1823 return;
1824 }
1825 setBootProperties(asyncResp, std::move(bootSource),
1826 std::move(bootEnable));
1827 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001828
Ed Tanous9712f8a2018-09-21 13:38:49 -07001829 if (indicatorLed)
1830 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301831 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001832 }
George Liuc6a620f2020-04-10 17:18:11 +08001833
1834 if (powerRestorePolicy)
1835 {
1836 setPowerRestorePolicy(asyncResp, std::move(*powerRestorePolicy));
1837 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001838 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001839};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001840} // namespace redfish