blob: 88590ee49b7c46e7db79bd613da65f01accfac83 [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"
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -080019#include "pcie.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080020#include "redfish_util.hpp"
21
Ed Tanous9712f8a2018-09-21 13:38:49 -070022#include <boost/container/flat_map.hpp>
23#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060024#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020025#include <utils/json_utils.hpp>
Ed Tanousabf2add2019-01-22 16:40:12 -080026#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020027
Ed Tanous1abe55e2018-09-05 08:30:59 -070028namespace redfish
29{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020030
Alpana Kumari9d3ae102019-04-12 06:49:32 -050031/**
32 * @brief Updates the Functional State of DIMMs
33 *
34 * @param[in] aResp Shared pointer for completing asynchronous calls
35 * @param[in] dimmState Dimm's Functional state, true/false
36 *
37 * @return None.
38 */
39void updateDimmProperties(std::shared_ptr<AsyncResp> aResp,
40 const std::variant<bool> &dimmState)
41{
42 const bool *isDimmFunctional = std::get_if<bool>(&dimmState);
43 if (isDimmFunctional == nullptr)
44 {
45 messages::internalError(aResp->res);
46 return;
47 }
Gunnar Mills698654b2019-10-16 13:17:37 -050048 BMCWEB_LOG_DEBUG << "Dimm Functional: " << *isDimmFunctional;
Alpana Kumari9d3ae102019-04-12 06:49:32 -050049
50 // Set it as Enabled if atleast one DIMM is functional
51 // Update STATE only if previous State was DISABLED and current Dimm is
52 // ENABLED.
53 nlohmann::json &prevMemSummary =
54 aResp->res.jsonValue["MemorySummary"]["Status"]["State"];
55 if (prevMemSummary == "Disabled")
56 {
57 if (*isDimmFunctional == true)
58 {
59 aResp->res.jsonValue["MemorySummary"]["Status"]["State"] =
60 "Enabled";
61 }
62 }
63}
64
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050065/*
66 * @brief Update "ProcessorSummary" "Count" based on Cpu PresenceState
67 *
68 * @param[in] aResp Shared pointer for completing asynchronous calls
69 * @param[in] cpuPresenceState CPU present or not
70 *
71 * @return None.
72 */
73void modifyCpuPresenceState(std::shared_ptr<AsyncResp> aResp,
74 const std::variant<bool> &cpuPresenceState)
75{
76 const bool *isCpuPresent = std::get_if<bool>(&cpuPresenceState);
77
78 if (isCpuPresent == nullptr)
79 {
80 messages::internalError(aResp->res);
81 return;
82 }
Gunnar Mills698654b2019-10-16 13:17:37 -050083 BMCWEB_LOG_DEBUG << "Cpu Present: " << *isCpuPresent;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -050084
85 nlohmann::json &procCount =
86 aResp->res.jsonValue["ProcessorSummary"]["Count"];
87 if (*isCpuPresent == true)
88 {
89 procCount = procCount.get<int>() + 1;
90 }
91 aResp->res.jsonValue["ProcessorSummary"]["Count"] = procCount;
92}
93
94/*
95 * @brief Update "ProcessorSummary" "Status" "State" based on
96 * CPU Functional State
97 *
98 * @param[in] aResp Shared pointer for completing asynchronous calls
99 * @param[in] cpuFunctionalState is CPU functional true/false
100 *
101 * @return None.
102 */
103void modifyCpuFunctionalState(std::shared_ptr<AsyncResp> aResp,
104 const std::variant<bool> &cpuFunctionalState)
105{
106 const bool *isCpuFunctional = std::get_if<bool>(&cpuFunctionalState);
107
108 if (isCpuFunctional == nullptr)
109 {
110 messages::internalError(aResp->res);
111 return;
112 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500113 BMCWEB_LOG_DEBUG << "Cpu Functional: " << *isCpuFunctional;
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500114
115 nlohmann::json &prevProcState =
116 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"];
117
118 // Set it as Enabled if atleast one CPU is functional
119 // Update STATE only if previous State was Non_Functional and current CPU is
120 // Functional.
121 if (prevProcState == "Disabled")
122 {
123 if (*isCpuFunctional == true)
124 {
125 aResp->res.jsonValue["ProcessorSummary"]["Status"]["State"] =
126 "Enabled";
127 }
128 }
129}
130
131/*
Ed Tanous6c34de42018-08-29 13:37:36 -0700132 * @brief Retrieves computer system properties over dbus
133 *
134 * @param[in] aResp Shared pointer for completing asynchronous calls
135 * @param[in] name Computer system name from request
136 *
137 * @return None.
138 */
James Feist5bc2dc82019-10-22 14:33:16 -0700139void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
140 std::shared_ptr<HealthPopulate> systemHealth)
Ed Tanous6c34de42018-08-29 13:37:36 -0700141{
Ed Tanous6c34de42018-08-29 13:37:36 -0700142 BMCWEB_LOG_DEBUG << "Get available system components.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500143
Ed Tanous6c34de42018-08-29 13:37:36 -0700144 crow::connections::systemBus->async_method_call(
James Feist5bc2dc82019-10-22 14:33:16 -0700145 [aResp, systemHealth](
Ed Tanous6c34de42018-08-29 13:37:36 -0700146 const boost::system::error_code ec,
147 const std::vector<std::pair<
148 std::string,
149 std::vector<std::pair<std::string, std::vector<std::string>>>>>
150 &subtree) {
151 if (ec)
152 {
153 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -0700154 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700155 return;
156 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700157 // Iterate over all retrieved ObjectPaths.
158 for (const std::pair<std::string,
159 std::vector<std::pair<
160 std::string, std::vector<std::string>>>>
161 &object : subtree)
162 {
163 const std::string &path = object.first;
164 BMCWEB_LOG_DEBUG << "Got path: " << path;
165 const std::vector<
166 std::pair<std::string, std::vector<std::string>>>
167 &connectionNames = object.second;
168 if (connectionNames.size() < 1)
169 {
170 continue;
171 }
Ed Tanous029573d2019-02-01 10:57:49 -0800172
James Feist5bc2dc82019-10-22 14:33:16 -0700173 auto memoryHealth = std::make_shared<HealthPopulate>(
174 aResp, aResp->res.jsonValue["MemorySummary"]["Status"]);
175
176 auto cpuHealth = std::make_shared<HealthPopulate>(
177 aResp, aResp->res.jsonValue["ProcessorSummary"]["Status"]);
178
179 systemHealth->children.emplace_back(memoryHealth);
180 systemHealth->children.emplace_back(cpuHealth);
181
Ed Tanous029573d2019-02-01 10:57:49 -0800182 // This is not system, so check if it's cpu, dimm, UUID or
183 // BiosVer
184 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700185 {
Ed Tanous029573d2019-02-01 10:57:49 -0800186 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700187 {
Ed Tanous029573d2019-02-01 10:57:49 -0800188 if (interfaceName ==
189 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700190 {
Ed Tanous029573d2019-02-01 10:57:49 -0800191 BMCWEB_LOG_DEBUG
192 << "Found Dimm, now get its properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500193
Ed Tanous029573d2019-02-01 10:57:49 -0800194 crow::connections::systemBus->async_method_call(
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500195 [aResp, service{connection.first},
196 path(std::move(path))](
197 const boost::system::error_code ec,
198 const std::vector<
199 std::pair<std::string, VariantType>>
200 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800201 if (ec)
202 {
203 BMCWEB_LOG_ERROR
204 << "DBUS response error " << ec;
205 messages::internalError(aResp->res);
206 return;
207 }
208 BMCWEB_LOG_DEBUG << "Got "
209 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500210 << " Dimm properties.";
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500211
212 if (properties.size() > 0)
Ed Tanous029573d2019-02-01 10:57:49 -0800213 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500214 for (const std::pair<std::string,
215 VariantType>
216 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700217 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500218 if (property.first ==
219 "MemorySizeInKb")
Ed Tanous6c34de42018-08-29 13:37:36 -0700220 {
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500221 const uint64_t *value =
222 sdbusplus::message::
223 variant_ns::get_if<
224 uint64_t>(
225 &property.second);
226 if (value != nullptr)
227 {
228 aResp->res.jsonValue
229 ["TotalSystemMemoryGi"
230 "B"] +=
231 *value / (1024 * 1024);
232 aResp->res.jsonValue
233 ["MemorySummary"]
234 ["Status"]["State"] =
235 "Enabled";
236 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700237 }
238 }
Ed Tanous029573d2019-02-01 10:57:49 -0800239 }
Alpana Kumari9d3ae102019-04-12 06:49:32 -0500240 else
241 {
242 auto getDimmProperties =
243 [aResp](
244 const boost::system::error_code
245 ec,
246 const std::variant<bool>
247 &dimmState) {
248 if (ec)
249 {
250 BMCWEB_LOG_ERROR
251 << "DBUS response "
252 "error "
253 << ec;
254 return;
255 }
256 updateDimmProperties(aResp,
257 dimmState);
258 };
259 crow::connections::systemBus
260 ->async_method_call(
261 std::move(getDimmProperties),
262 service, path,
263 "org.freedesktop.DBus."
264 "Properties",
265 "Get",
266 "xyz.openbmc_project.State."
267 "Decorator.OperationalStatus",
268 "Functional");
269 }
Ed Tanous029573d2019-02-01 10:57:49 -0800270 },
271 connection.first, path,
272 "org.freedesktop.DBus.Properties", "GetAll",
273 "xyz.openbmc_project.Inventory.Item.Dimm");
James Feist5bc2dc82019-10-22 14:33:16 -0700274
275 memoryHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800276 }
277 else if (interfaceName ==
278 "xyz.openbmc_project.Inventory.Item.Cpu")
279 {
280 BMCWEB_LOG_DEBUG
281 << "Found Cpu, now get its properties.";
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500282
Ed Tanous029573d2019-02-01 10:57:49 -0800283 crow::connections::systemBus->async_method_call(
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500284 [aResp, service{connection.first},
285 path(std::move(path))](
286 const boost::system::error_code ec,
287 const std::vector<
288 std::pair<std::string, VariantType>>
289 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800290 if (ec)
291 {
292 BMCWEB_LOG_ERROR
293 << "DBUS response error " << ec;
294 messages::internalError(aResp->res);
295 return;
296 }
297 BMCWEB_LOG_DEBUG << "Got "
298 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500299 << " Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700300
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500301 if (properties.size() > 0)
302 {
303 for (const auto &property : properties)
304 {
305 if (property.first ==
306 "ProcessorFamily")
307 {
308 const std::string *value =
309 sdbusplus::message::
310 variant_ns::get_if<
311 std::string>(
312 &property.second);
313 if (value != nullptr)
314 {
315 nlohmann::json
316 &procSummary =
317 aResp->res.jsonValue
318 ["ProcessorSumm"
319 "ary"];
320 nlohmann::json &procCount =
321 procSummary["Count"];
322 procCount =
323 procCount.get<int>() +
324 1;
325 procSummary["Status"]
326 ["State"] =
327 "Enabled";
328 procSummary["Model"] =
329 *value;
330 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700331 }
332 }
Ed Tanous029573d2019-02-01 10:57:49 -0800333 }
Alpana Kumari57e8c9b2019-04-15 01:09:36 -0500334 else
335 {
336 auto getCpuPresenceState =
337 [aResp](
338 const boost::system::error_code
339 ec,
340 const std::variant<bool>
341 &cpuPresenceCheck) {
342 if (ec)
343 {
344 BMCWEB_LOG_ERROR
345 << "DBUS response "
346 "error "
347 << ec;
348 return;
349 }
350 modifyCpuPresenceState(
351 aResp, cpuPresenceCheck);
352 };
353
354 auto getCpuFunctionalState =
355 [aResp](
356 const boost::system::error_code
357 ec,
358 const std::variant<bool>
359 &cpuFunctionalCheck) {
360 if (ec)
361 {
362 BMCWEB_LOG_ERROR
363 << "DBUS response "
364 "error "
365 << ec;
366 return;
367 }
368 modifyCpuFunctionalState(
369 aResp, cpuFunctionalCheck);
370 };
371 // Get the Presence of CPU
372 crow::connections::systemBus
373 ->async_method_call(
374 std::move(getCpuPresenceState),
375 service, path,
376 "org.freedesktop.DBus."
377 "Properties",
378 "Get",
379 "xyz.openbmc_project.Inventory."
380 "Item",
381 "Present");
382
383 // Get the Functional State
384 crow::connections::systemBus
385 ->async_method_call(
386 std::move(
387 getCpuFunctionalState),
388 service, path,
389 "org.freedesktop.DBus."
390 "Properties",
391 "Get",
392 "xyz.openbmc_project.State."
393 "Decorator."
394 "OperationalStatus",
395 "Functional");
396
397 // Get the MODEL from
398 // xyz.openbmc_project.Inventory.Decorator.Asset
399 // support it later as Model is Empty
400 // currently.
401 }
Ed Tanous029573d2019-02-01 10:57:49 -0800402 },
403 connection.first, path,
404 "org.freedesktop.DBus.Properties", "GetAll",
405 "xyz.openbmc_project.Inventory.Item.Cpu");
James Feist5bc2dc82019-10-22 14:33:16 -0700406
407 cpuHealth->inventory.emplace_back(path);
Ed Tanous029573d2019-02-01 10:57:49 -0800408 }
409 else if (interfaceName ==
410 "xyz.openbmc_project.Common.UUID")
411 {
412 BMCWEB_LOG_DEBUG
413 << "Found UUID, now get its properties.";
414 crow::connections::systemBus->async_method_call(
415 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700416 const std::vector<
417 std::pair<std::string, VariantType>>
418 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800419 if (ec)
420 {
421 BMCWEB_LOG_DEBUG
422 << "DBUS response error " << ec;
423 messages::internalError(aResp->res);
424 return;
425 }
426 BMCWEB_LOG_DEBUG << "Got "
427 << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500428 << " UUID properties.";
Ed Tanous029573d2019-02-01 10:57:49 -0800429 for (const std::pair<std::string,
430 VariantType>
431 &property : properties)
432 {
Ed Tanous029573d2019-02-01 10:57:49 -0800433 if (property.first == "UUID")
434 {
435 const std::string *value =
436 sdbusplus::message::variant_ns::
437 get_if<std::string>(
438 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700439
Ed Tanous029573d2019-02-01 10:57:49 -0800440 if (value != nullptr)
441 {
442 std::string valueStr = *value;
443 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700444 {
Ed Tanous029573d2019-02-01 10:57:49 -0800445 valueStr.insert(8, 1, '-');
446 valueStr.insert(13, 1, '-');
447 valueStr.insert(18, 1, '-');
448 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700449 }
Ed Tanous029573d2019-02-01 10:57:49 -0800450 BMCWEB_LOG_DEBUG << "UUID = "
451 << valueStr;
452 aResp->res.jsonValue["UUID"] =
453 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700454 }
455 }
Ed Tanous029573d2019-02-01 10:57:49 -0800456 }
457 },
458 connection.first, path,
459 "org.freedesktop.DBus.Properties", "GetAll",
460 "xyz.openbmc_project.Common.UUID");
461 }
462 else if (interfaceName ==
463 "xyz.openbmc_project.Inventory.Item.System")
464 {
465 crow::connections::systemBus->async_method_call(
466 [aResp](const boost::system::error_code ec,
467 const std::vector<
468 std::pair<std::string, VariantType>>
469 &propertiesList) {
470 if (ec)
471 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700472 // doesn't have to include this
473 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800474 return;
475 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500476 BMCWEB_LOG_DEBUG
477 << "Got " << propertiesList.size()
478 << " properties for system";
Ed Tanous029573d2019-02-01 10:57:49 -0800479 for (const std::pair<std::string,
480 VariantType>
481 &property : propertiesList)
482 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600483 const std::string &propertyName =
484 property.first;
485 if ((propertyName == "PartNumber") ||
486 (propertyName == "SerialNumber") ||
487 (propertyName == "Manufacturer") ||
488 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800489 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600490 const std::string *value =
491 std::get_if<std::string>(
492 &property.second);
493 if (value != nullptr)
494 {
495 aResp->res
496 .jsonValue[propertyName] =
497 *value;
498 }
Ed Tanous029573d2019-02-01 10:57:49 -0800499 }
500 }
501 aResp->res.jsonValue["Name"] = "system";
502 aResp->res.jsonValue["Id"] =
503 aResp->res.jsonValue["SerialNumber"];
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600504 // Grab the bios version
505 fw_util::getActiveFwVersion(
506 aResp, fw_util::biosPurpose,
507 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800508 },
509 connection.first, path,
510 "org.freedesktop.DBus.Properties", "GetAll",
511 "xyz.openbmc_project.Inventory.Decorator."
512 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700513
514 crow::connections::systemBus->async_method_call(
515 [aResp](
516 const boost::system::error_code ec,
517 const std::variant<std::string> &property) {
518 if (ec)
519 {
520 // doesn't have to include this
521 // interface
522 return;
523 }
524
525 const std::string *value =
526 std::get_if<std::string>(&property);
527 if (value != nullptr)
528 {
529 aResp->res.jsonValue["AssetTag"] =
530 *value;
531 }
532 },
533 connection.first, path,
534 "org.freedesktop.DBus.Properties", "Get",
535 "xyz.openbmc_project.Inventory.Decorator."
536 "AssetTag",
537 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700538 }
539 }
540 }
541 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700542 },
543 "xyz.openbmc_project.ObjectMapper",
544 "/xyz/openbmc_project/object_mapper",
545 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700546 "/xyz/openbmc_project/inventory", int32_t(0),
547 std::array<const char *, 5>{
548 "xyz.openbmc_project.Inventory.Decorator.Asset",
549 "xyz.openbmc_project.Inventory.Item.Cpu",
550 "xyz.openbmc_project.Inventory.Item.Dimm",
551 "xyz.openbmc_project.Inventory.Item.System",
552 "xyz.openbmc_project.Common.UUID",
553 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700554}
555
556/**
557 * @brief Retrieves identify led group properties over dbus
558 *
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530559 * @param[in] aResp Shared pointer for generating response message.
Ed Tanous6c34de42018-08-29 13:37:36 -0700560 *
561 * @return None.
562 */
AppaRao Pulia3002222019-11-12 21:32:59 +0530563void getIndicatorLedState(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -0700564{
565 BMCWEB_LOG_DEBUG << "Get led groups";
566 crow::connections::systemBus->async_method_call(
AppaRao Pulia3002222019-11-12 21:32:59 +0530567 [aResp](const boost::system::error_code ec,
568 const std::variant<bool> asserted) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700569 if (ec)
570 {
571 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700572 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700573 return;
574 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530575
576 const bool *blinking = std::get_if<bool>(&asserted);
577 if (!blinking)
Ed Tanous6c34de42018-08-29 13:37:36 -0700578 {
AppaRao Pulia3002222019-11-12 21:32:59 +0530579 BMCWEB_LOG_DEBUG << "Get identity blinking LED failed";
580 messages::internalError(aResp->res);
581 return;
582 }
583 // Blinking ON, no need to check enclosure_identify assert.
584 if (*blinking)
585 {
586 aResp->res.jsonValue["IndicatorLED"] = "Blinking";
587 return;
588 }
589 crow::connections::systemBus->async_method_call(
590 [aResp](const boost::system::error_code ec,
591 const std::variant<bool> asserted) {
592 if (ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700593 {
AppaRao Pulia3002222019-11-12 21:32:59 +0530594 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
595 messages::internalError(aResp->res);
596 return;
Ed Tanous6c34de42018-08-29 13:37:36 -0700597 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530598
599 const bool *ledOn = std::get_if<bool>(&asserted);
600 if (!ledOn)
601 {
602 BMCWEB_LOG_DEBUG << "Get enclosure identity led failed";
603 messages::internalError(aResp->res);
604 return;
605 }
606
607 if (*ledOn)
608 {
609 aResp->res.jsonValue["IndicatorLED"] = "Lit";
610 }
611 else
612 {
613 aResp->res.jsonValue["IndicatorLED"] = "Off";
614 }
615 return;
616 },
617 "xyz.openbmc_project.LED.GroupManager",
618 "/xyz/openbmc_project/led/groups/enclosure_identify",
619 "org.freedesktop.DBus.Properties", "Get",
620 "xyz.openbmc_project.Led.Group", "Asserted");
621 },
622 "xyz.openbmc_project.LED.GroupManager",
623 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
624 "org.freedesktop.DBus.Properties", "Get",
625 "xyz.openbmc_project.Led.Group", "Asserted");
626}
627/**
628 * @brief Sets identify led group properties
629 *
630 * @param[in] aResp Shared pointer for generating response message.
631 * @param[in] ledState LED state passed from request
632 *
633 * @return None.
634 */
635void setIndicatorLedState(std::shared_ptr<AsyncResp> aResp,
636 const std::string &ledState)
637{
638 BMCWEB_LOG_DEBUG << "Set led groups";
639 bool ledOn = false;
640 bool ledBlinkng = false;
641
642 if (ledState == "Lit")
643 {
644 ledOn = true;
645 }
646 else if (ledState == "Blinking")
647 {
648 ledBlinkng = true;
649 }
650 else if (ledState != "Off")
651 {
652 messages::propertyValueNotInList(aResp->res, ledState, "IndicatorLED");
653 return;
654 }
655
656 crow::connections::systemBus->async_method_call(
657 [aResp](const boost::system::error_code ec,
658 const std::variant<bool> asserted) {
659 if (ec)
660 {
661 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
662 messages::internalError(aResp->res);
663 return;
Ed Tanous6c34de42018-08-29 13:37:36 -0700664 }
665 },
666 "xyz.openbmc_project.LED.GroupManager",
AppaRao Pulia3002222019-11-12 21:32:59 +0530667 "/xyz/openbmc_project/led/groups/enclosure_identify",
668 "org.freedesktop.DBus.Properties", "Set",
669 "xyz.openbmc_project.Led.Group", "Asserted", std::variant<bool>(ledOn));
670
671 crow::connections::systemBus->async_method_call(
672 [aResp](const boost::system::error_code ec,
673 const std::variant<bool> asserted) {
674 if (ec)
675 {
676 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
677 messages::internalError(aResp->res);
678 return;
679 }
680 },
681 "xyz.openbmc_project.LED.GroupManager",
682 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
683 "org.freedesktop.DBus.Properties", "Set",
684 "xyz.openbmc_project.Led.Group", "Asserted",
685 std::variant<bool>(ledBlinkng));
Ed Tanous6c34de42018-08-29 13:37:36 -0700686}
687
Ed Tanous6c34de42018-08-29 13:37:36 -0700688/**
689 * @brief Retrieves host state properties over dbus
690 *
691 * @param[in] aResp Shared pointer for completing asynchronous calls.
692 *
693 * @return None.
694 */
695void getHostState(std::shared_ptr<AsyncResp> aResp)
696{
697 BMCWEB_LOG_DEBUG << "Get host information.";
698 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800699 [aResp](const boost::system::error_code ec,
700 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700701 if (ec)
702 {
703 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700704 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700705 return;
706 }
Ed Tanous66173382018-08-15 18:20:59 -0700707
Ed Tanousabf2add2019-01-22 16:40:12 -0800708 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700709 BMCWEB_LOG_DEBUG << "Host state: " << *s;
710 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700711 {
Ed Tanous66173382018-08-15 18:20:59 -0700712 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800713 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700714 {
Ed Tanous66173382018-08-15 18:20:59 -0700715 aResp->res.jsonValue["PowerState"] = "On";
716 aResp->res.jsonValue["Status"]["State"] = "Enabled";
717 }
718 else
719 {
720 aResp->res.jsonValue["PowerState"] = "Off";
721 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700722 }
723 }
724 },
725 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700726 "org.freedesktop.DBus.Properties", "Get",
727 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700728}
729
730/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530731 * @brief Traslates boot source DBUS property value to redfish.
732 *
733 * @param[in] dbusSource The boot source in DBUS speak.
734 *
735 * @return Returns as a string, the boot source in Redfish terms. If translation
736 * cannot be done, returns an empty string.
737 */
738static std::string dbusToRfBootSource(const std::string &dbusSource)
739{
740 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
741 {
742 return "None";
743 }
744 else if (dbusSource ==
745 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
746 {
747 return "Hdd";
748 }
749 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530750 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530751 {
752 return "Cd";
753 }
754 else if (dbusSource ==
755 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
756 {
757 return "Pxe";
758 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700759 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700760 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700761 {
762 return "Usb";
763 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530764 else
765 {
766 return "";
767 }
768}
769
770/**
771 * @brief Traslates boot mode DBUS property value to redfish.
772 *
773 * @param[in] dbusMode The boot mode in DBUS speak.
774 *
775 * @return Returns as a string, the boot mode in Redfish terms. If translation
776 * cannot be done, returns an empty string.
777 */
778static std::string dbusToRfBootMode(const std::string &dbusMode)
779{
780 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
781 {
782 return "None";
783 }
784 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
785 {
786 return "Diags";
787 }
788 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
789 {
790 return "BiosSetup";
791 }
792 else
793 {
794 return "";
795 }
796}
797
798/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700799 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530800 *
801 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700802 * @param[out] bootSource The DBus source
803 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530804 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700805 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530806 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700807static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
808 const std::string &rfSource,
809 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530810{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700811 // The caller has initialized the bootSource and bootMode to:
812 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
813 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
814 // Only modify the bootSource/bootMode variable needed to achieve the
815 // desired boot action.
816
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530817 if (rfSource == "None")
818 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700819 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530820 }
821 else if (rfSource == "Pxe")
822 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700823 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
824 }
825 else if (rfSource == "Hdd")
826 {
827 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
828 }
829 else if (rfSource == "Diags")
830 {
831 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
832 }
833 else if (rfSource == "Cd")
834 {
835 bootSource =
836 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
837 }
838 else if (rfSource == "BiosSetup")
839 {
840 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530841 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700842 else if (rfSource == "Usb")
843 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700844 bootSource =
845 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700846 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530847 else
848 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700849 BMCWEB_LOG_DEBUG << "Invalid property value for "
850 "BootSourceOverrideTarget: "
851 << bootSource;
852 messages::propertyValueNotInList(aResp->res, rfSource,
853 "BootSourceTargetOverride");
854 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530855 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700856 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530857}
858
859/**
860 * @brief Retrieves boot mode over DBUS and fills out the response
861 *
862 * @param[in] aResp Shared pointer for generating response message.
863 * @param[in] bootDbusObj The dbus object to query for boot properties.
864 *
865 * @return None.
866 */
867static void getBootMode(std::shared_ptr<AsyncResp> aResp,
868 std::string bootDbusObj)
869{
870 crow::connections::systemBus->async_method_call(
871 [aResp](const boost::system::error_code ec,
872 const std::variant<std::string> &bootMode) {
873 if (ec)
874 {
875 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
876 messages::internalError(aResp->res);
877 return;
878 }
879
880 const std::string *bootModeStr =
881 std::get_if<std::string>(&bootMode);
882
883 if (!bootModeStr)
884 {
885 messages::internalError(aResp->res);
886 return;
887 }
888
889 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
890
891 // TODO (Santosh): Do we need to support override mode?
892 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
893 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
894 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700895 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530896
897 if (*bootModeStr !=
898 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
899 {
900 auto rfMode = dbusToRfBootMode(*bootModeStr);
901 if (!rfMode.empty())
902 {
903 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
904 rfMode;
905 }
906 }
907
908 // If the BootSourceOverrideTarget is still "None" at the end,
909 // reset the BootSourceOverrideEnabled to indicate that
910 // overrides are disabled
911 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
912 "None")
913 {
914 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
915 "Disabled";
916 }
917 },
918 "xyz.openbmc_project.Settings", bootDbusObj,
919 "org.freedesktop.DBus.Properties", "Get",
920 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
921}
922
923/**
924 * @brief Retrieves boot source over DBUS
925 *
926 * @param[in] aResp Shared pointer for generating response message.
927 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
928 *
929 * @return None.
930 */
931static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
932{
933 std::string bootDbusObj =
934 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
935 : "/xyz/openbmc_project/control/host0/boot";
936
937 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
938 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
939 (oneTimeEnabled) ? "Once" : "Continuous";
940
941 crow::connections::systemBus->async_method_call(
942 [aResp, bootDbusObj](const boost::system::error_code ec,
943 const std::variant<std::string> &bootSource) {
944 if (ec)
945 {
946 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
947 messages::internalError(aResp->res);
948 return;
949 }
950
951 const std::string *bootSourceStr =
952 std::get_if<std::string>(&bootSource);
953
954 if (!bootSourceStr)
955 {
956 messages::internalError(aResp->res);
957 return;
958 }
959 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
960
961 auto rfSource = dbusToRfBootSource(*bootSourceStr);
962 if (!rfSource.empty())
963 {
964 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
965 rfSource;
966 }
967 },
968 "xyz.openbmc_project.Settings", bootDbusObj,
969 "org.freedesktop.DBus.Properties", "Get",
970 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
971 getBootMode(std::move(aResp), std::move(bootDbusObj));
972}
973
974/**
975 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
976 * get boot source and boot mode.
977 *
978 * @param[in] aResp Shared pointer for generating response message.
979 *
980 * @return None.
981 */
982static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
983{
984 BMCWEB_LOG_DEBUG << "Get boot information.";
985
986 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800987 [aResp](const boost::system::error_code ec,
988 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530989 if (ec)
990 {
991 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700992 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530993 return;
994 }
995
996 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
997
998 if (!oneTimePtr)
999 {
1000 messages::internalError(aResp->res);
1001 return;
1002 }
1003 getBootSource(aResp, *oneTimePtr);
1004 },
1005 "xyz.openbmc_project.Settings",
1006 "/xyz/openbmc_project/control/host0/boot/one_time",
1007 "org.freedesktop.DBus.Properties", "Get",
1008 "xyz.openbmc_project.Object.Enable", "Enabled");
1009}
1010
1011/**
1012 * @brief Sets boot properties into DBUS object(s).
1013 *
1014 * @param[in] aResp Shared pointer for generating response message.
1015 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1016 * @param[in] bootSource The boot source to set.
1017 * @param[in] bootEnable The source override "enable" to set.
1018 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001019 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301020 */
1021static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1022 bool oneTimeEnabled,
1023 std::optional<std::string> bootSource,
1024 std::optional<std::string> bootEnable)
1025{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001026 std::string bootSourceStr =
1027 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1028 std::string bootModeStr =
1029 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001031 bool useBootSource = true;
1032
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301033 // Validate incoming parameters
1034 if (bootEnable)
1035 {
1036 if (*bootEnable == "Once")
1037 {
1038 oneTimeSetting = true;
1039 }
1040 else if (*bootEnable == "Continuous")
1041 {
1042 oneTimeSetting = false;
1043 }
1044 else if (*bootEnable == "Disabled")
1045 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001046 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301047 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001048 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301049 }
1050 else
1051 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301052 BMCWEB_LOG_DEBUG << "Unsupported value for "
1053 "BootSourceOverrideEnabled: "
1054 << *bootEnable;
1055 messages::propertyValueNotInList(aResp->res, *bootEnable,
1056 "BootSourceOverrideEnabled");
1057 return;
1058 }
1059 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301060
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001061 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301062 {
1063 // Source target specified
1064 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1065 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001066 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1067 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301068 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001069 BMCWEB_LOG_DEBUG
1070 << "Invalid property value for BootSourceOverrideTarget: "
1071 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301072 messages::propertyValueNotInList(aResp->res, *bootSource,
1073 "BootSourceTargetOverride");
1074 return;
1075 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001076 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301077
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001078 // Act on validated parameters
1079 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1080 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1081 const char *bootObj =
1082 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1083 : "/xyz/openbmc_project/control/host0/boot";
1084
1085 crow::connections::systemBus->async_method_call(
1086 [aResp](const boost::system::error_code ec) {
1087 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301088 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001089 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1090 messages::internalError(aResp->res);
1091 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301092 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001093 BMCWEB_LOG_DEBUG << "Boot source update done.";
1094 },
1095 "xyz.openbmc_project.Settings", bootObj,
1096 "org.freedesktop.DBus.Properties", "Set",
1097 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1098 std::variant<std::string>(bootSourceStr));
1099
1100 crow::connections::systemBus->async_method_call(
1101 [aResp](const boost::system::error_code ec) {
1102 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301103 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001104 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1105 messages::internalError(aResp->res);
1106 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301107 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001108 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1109 },
1110 "xyz.openbmc_project.Settings", bootObj,
1111 "org.freedesktop.DBus.Properties", "Set",
1112 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1113 std::variant<std::string>(bootModeStr));
1114
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301115 crow::connections::systemBus->async_method_call(
1116 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1117 if (ec)
1118 {
1119 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1120 messages::internalError(aResp->res);
1121 return;
1122 }
1123 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1124 },
1125 "xyz.openbmc_project.Settings",
1126 "/xyz/openbmc_project/control/host0/boot/one_time",
1127 "org.freedesktop.DBus.Properties", "Set",
1128 "xyz.openbmc_project.Object.Enable", "Enabled",
1129 std::variant<bool>(oneTimeSetting));
1130}
1131
1132/**
1133 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1134 * set boot source/boot mode properties.
1135 *
1136 * @param[in] aResp Shared pointer for generating response message.
1137 * @param[in] bootSource The boot source from incoming RF request.
1138 * @param[in] bootEnable The boot override enable from incoming RF request.
1139 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001140 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301141 */
1142static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1143 std::optional<std::string> bootSource,
1144 std::optional<std::string> bootEnable)
1145{
1146 BMCWEB_LOG_DEBUG << "Set boot information.";
1147
1148 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001149 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301150 bootEnable{std::move(bootEnable)}](
1151 const boost::system::error_code ec,
1152 const sdbusplus::message::variant<bool> &oneTime) {
1153 if (ec)
1154 {
1155 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1156 messages::internalError(aResp->res);
1157 return;
1158 }
1159
1160 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1161
1162 if (!oneTimePtr)
1163 {
1164 messages::internalError(aResp->res);
1165 return;
1166 }
1167
1168 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1169
1170 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1171 std::move(bootEnable));
1172 },
1173 "xyz.openbmc_project.Settings",
1174 "/xyz/openbmc_project/control/host0/boot/one_time",
1175 "org.freedesktop.DBus.Properties", "Get",
1176 "xyz.openbmc_project.Object.Enable", "Enabled");
1177}
1178
AppaRao Pulia6349912019-10-18 17:16:08 +05301179#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1180/**
1181 * @brief Retrieves provisioning status
1182 *
1183 * @param[in] aResp Shared pointer for completing asynchronous calls.
1184 *
1185 * @return None.
1186 */
1187void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1188{
1189 BMCWEB_LOG_DEBUG << "Get OEM information.";
1190 crow::connections::systemBus->async_method_call(
1191 [aResp](const boost::system::error_code ec,
1192 const std::vector<std::pair<std::string, VariantType>>
1193 &propertiesList) {
1194 if (ec)
1195 {
1196 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1197 messages::internalError(aResp->res);
1198 return;
1199 }
1200
1201 const bool *provState = nullptr;
1202 const bool *lockState = nullptr;
1203 for (const std::pair<std::string, VariantType> &property :
1204 propertiesList)
1205 {
1206 if (property.first == "UfmProvisioned")
1207 {
1208 provState = std::get_if<bool>(&property.second);
1209 }
1210 else if (property.first == "UfmLocked")
1211 {
1212 lockState = std::get_if<bool>(&property.second);
1213 }
1214 }
1215
1216 if ((provState == nullptr) || (lockState == nullptr))
1217 {
1218 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1219 messages::internalError(aResp->res);
1220 return;
1221 }
1222
1223 nlohmann::json &oemPFR =
1224 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1225 if (*provState == true)
1226 {
1227 if (*lockState == true)
1228 {
1229 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1230 }
1231 else
1232 {
1233 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1234 }
1235 }
1236 else
1237 {
1238 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1239 }
1240 },
1241 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1242 "org.freedesktop.DBus.Properties", "GetAll",
1243 "xyz.openbmc_project.PFR.Attributes");
1244}
1245#endif
1246
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301247/**
Yong Li51709ff2019-09-30 14:13:04 +08001248 * @brief Translates watchdog timeout action DBUS property value to redfish.
1249 *
1250 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1251 *
1252 * @return Returns as a string, the timeout action in Redfish terms. If
1253 * translation cannot be done, returns an empty string.
1254 */
1255static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1256{
1257 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1258 {
1259 return "None";
1260 }
1261 else if (dbusAction ==
1262 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1263 {
1264 return "ResetSystem";
1265 }
1266 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1267 {
1268 return "PowerDown";
1269 }
1270 else if (dbusAction ==
1271 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1272 {
1273 return "PowerCycle";
1274 }
1275
1276 return "";
1277}
1278
1279/**
Yong Lic45f0082019-10-10 14:19:01 +08001280 *@brief Translates timeout action from Redfish to DBUS property value.
1281 *
1282 *@param[in] rfAction The timeout action in Redfish.
1283 *
1284 *@return Returns as a string, the time_out action as expected by DBUS.
1285 *If translation cannot be done, returns an empty string.
1286 */
1287
1288static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1289{
1290 if (rfAction == "None")
1291 {
1292 return "xyz.openbmc_project.State.Watchdog.Action.None";
1293 }
1294 else if (rfAction == "PowerCycle")
1295 {
1296 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1297 }
1298 else if (rfAction == "PowerDown")
1299 {
1300 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1301 }
1302 else if (rfAction == "ResetSystem")
1303 {
1304 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1305 }
1306
1307 return "";
1308}
1309
1310/**
Yong Li51709ff2019-09-30 14:13:04 +08001311 * @brief Retrieves host watchdog timer properties over DBUS
1312 *
1313 * @param[in] aResp Shared pointer for completing asynchronous calls.
1314 *
1315 * @return None.
1316 */
1317void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1318{
1319 BMCWEB_LOG_DEBUG << "Get host watchodg";
1320 crow::connections::systemBus->async_method_call(
1321 [aResp](const boost::system::error_code ec,
1322 PropertiesType &properties) {
1323 if (ec)
1324 {
1325 // watchdog service is stopped
1326 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1327 return;
1328 }
1329
1330 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1331
1332 nlohmann::json &hostWatchdogTimer =
1333 aResp->res.jsonValue["HostWatchdogTimer"];
1334
1335 // watchdog service is running/enabled
1336 hostWatchdogTimer["Status"]["State"] = "Enabled";
1337
1338 for (const auto &property : properties)
1339 {
1340 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1341 if (property.first == "Enabled")
1342 {
1343 const bool *state = std::get_if<bool>(&property.second);
1344
1345 if (!state)
1346 {
1347 messages::internalError(aResp->res);
1348 continue;
1349 }
1350
1351 hostWatchdogTimer["FunctionEnabled"] = *state;
1352 }
1353 else if (property.first == "ExpireAction")
1354 {
1355 const std::string *s =
1356 std::get_if<std::string>(&property.second);
1357 if (!s)
1358 {
1359 messages::internalError(aResp->res);
1360 continue;
1361 }
1362
1363 std::string action = dbusToRfWatchdogAction(*s);
1364 if (action.empty())
1365 {
1366 messages::internalError(aResp->res);
1367 continue;
1368 }
1369 hostWatchdogTimer["TimeoutAction"] = action;
1370 }
1371 }
1372 },
1373 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1374 "org.freedesktop.DBus.Properties", "GetAll",
1375 "xyz.openbmc_project.State.Watchdog");
1376}
1377
1378/**
Yong Lic45f0082019-10-10 14:19:01 +08001379 * @brief Sets Host WatchDog Timer properties.
1380 *
1381 * @param[in] aResp Shared pointer for generating response message.
1382 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1383 * RF request.
1384 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1385 *
1386 * @return None.
1387 */
1388static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1389 const std::optional<bool> wdtEnable,
1390 const std::optional<std::string> &wdtTimeOutAction)
1391{
1392 BMCWEB_LOG_DEBUG << "Set host watchdog";
1393
1394 if (wdtTimeOutAction)
1395 {
1396 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1397 // check if TimeOut Action is Valid
1398 if (wdtTimeOutActStr.empty())
1399 {
1400 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1401 << *wdtTimeOutAction;
1402 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1403 "TimeoutAction");
1404 return;
1405 }
1406
1407 crow::connections::systemBus->async_method_call(
1408 [aResp](const boost::system::error_code ec) {
1409 if (ec)
1410 {
1411 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1412 messages::internalError(aResp->res);
1413 return;
1414 }
1415 },
1416 "xyz.openbmc_project.Watchdog",
1417 "/xyz/openbmc_project/watchdog/host0",
1418 "org.freedesktop.DBus.Properties", "Set",
1419 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1420 std::variant<std::string>(wdtTimeOutActStr));
1421 }
1422
1423 if (wdtEnable)
1424 {
1425 crow::connections::systemBus->async_method_call(
1426 [aResp](const boost::system::error_code ec) {
1427 if (ec)
1428 {
1429 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1430 messages::internalError(aResp->res);
1431 return;
1432 }
1433 },
1434 "xyz.openbmc_project.Watchdog",
1435 "/xyz/openbmc_project/watchdog/host0",
1436 "org.freedesktop.DBus.Properties", "Set",
1437 "xyz.openbmc_project.State.Watchdog", "Enabled",
1438 std::variant<bool>(*wdtEnable));
1439 }
1440}
1441
1442/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001443 * SystemsCollection derived class for delivering ComputerSystems Collection
1444 * Schema
1445 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001446class SystemsCollection : public Node
1447{
1448 public:
1449 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1450 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001451 entityPrivileges = {
1452 {boost::beast::http::verb::get, {{"Login"}}},
1453 {boost::beast::http::verb::head, {{"Login"}}},
1454 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1455 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1456 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1457 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1458 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001459
Ed Tanous1abe55e2018-09-05 08:30:59 -07001460 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001461 void doGet(crow::Response &res, const crow::Request &req,
1462 const std::vector<std::string> &params) override
1463 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001464 res.jsonValue["@odata.type"] =
1465 "#ComputerSystemCollection.ComputerSystemCollection";
1466 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1467 res.jsonValue["@odata.context"] =
1468 "/redfish/v1/"
1469 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1470 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001471 res.jsonValue["Members"] = {
1472 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1473 res.jsonValue["Members@odata.count"] = 1;
1474 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001475 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001476};
1477
1478/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001479 * SystemActionsReset class supports handle POST method for Reset action.
1480 * The class retrieves and sends data directly to D-Bus.
1481 */
1482class SystemActionsReset : public Node
1483{
1484 public:
1485 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001486 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001487 {
1488 entityPrivileges = {
1489 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1490 }
1491
1492 private:
1493 /**
1494 * Function handles POST method request.
1495 * Analyzes POST body message before sends Reset request data to D-Bus.
1496 */
1497 void doPost(crow::Response &res, const crow::Request &req,
1498 const std::vector<std::string> &params) override
1499 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001500 auto asyncResp = std::make_shared<AsyncResp>(res);
1501
1502 std::string resetType;
1503 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001504 {
1505 return;
1506 }
1507
Jason M. Billsd22c8392019-06-03 13:59:03 -07001508 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001509 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001510 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001511 if (resetType == "On")
1512 {
1513 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001514 hostCommand = true;
1515 }
1516 else if (resetType == "ForceOff")
1517 {
1518 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1519 hostCommand = false;
1520 }
1521 else if (resetType == "ForceOn")
1522 {
1523 command = "xyz.openbmc_project.State.Host.Transition.On";
1524 hostCommand = true;
1525 }
1526 else if (resetType == "ForceRestart")
1527 {
1528 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1529 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001530 }
1531 else if (resetType == "GracefulShutdown")
1532 {
1533 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001534 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001535 }
1536 else if (resetType == "GracefulRestart")
1537 {
1538 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001539 hostCommand = true;
1540 }
1541 else if (resetType == "PowerCycle")
1542 {
1543 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1544 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001545 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001546 else if (resetType == "Nmi")
1547 {
1548 doNMI(asyncResp);
1549 return;
1550 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001551 else
1552 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001553 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001554 return;
1555 }
1556
Jason M. Billsd22c8392019-06-03 13:59:03 -07001557 if (hostCommand)
1558 {
1559 crow::connections::systemBus->async_method_call(
1560 [asyncResp, resetType](const boost::system::error_code ec) {
1561 if (ec)
1562 {
1563 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1564 if (ec.value() == boost::asio::error::invalid_argument)
1565 {
1566 messages::actionParameterNotSupported(
1567 asyncResp->res, resetType, "Reset");
1568 }
1569 else
1570 {
1571 messages::internalError(asyncResp->res);
1572 }
1573 return;
1574 }
1575 messages::success(asyncResp->res);
1576 },
1577 "xyz.openbmc_project.State.Host",
1578 "/xyz/openbmc_project/state/host0",
1579 "org.freedesktop.DBus.Properties", "Set",
1580 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1581 std::variant<std::string>{command});
1582 }
1583 else
1584 {
1585 crow::connections::systemBus->async_method_call(
1586 [asyncResp, resetType](const boost::system::error_code ec) {
1587 if (ec)
1588 {
1589 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1590 if (ec.value() == boost::asio::error::invalid_argument)
1591 {
1592 messages::actionParameterNotSupported(
1593 asyncResp->res, resetType, "Reset");
1594 }
1595 else
1596 {
1597 messages::internalError(asyncResp->res);
1598 }
1599 return;
1600 }
1601 messages::success(asyncResp->res);
1602 },
1603 "xyz.openbmc_project.State.Chassis",
1604 "/xyz/openbmc_project/state/chassis0",
1605 "org.freedesktop.DBus.Properties", "Set",
1606 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1607 std::variant<std::string>{command});
1608 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001609 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001610 /**
1611 * Function transceives data with dbus directly.
1612 */
1613 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1614 {
1615 constexpr char const *serviceName =
1616 "xyz.openbmc_project.Control.Host.NMI";
1617 constexpr char const *objectPath =
1618 "/xyz/openbmc_project/control/host0/nmi";
1619 constexpr char const *interfaceName =
1620 "xyz.openbmc_project.Control.Host.NMI";
1621 constexpr char const *method = "NMI";
1622
1623 crow::connections::systemBus->async_method_call(
1624 [asyncResp](const boost::system::error_code ec) {
1625 if (ec)
1626 {
1627 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1628 messages::internalError(asyncResp->res);
1629 return;
1630 }
1631 messages::success(asyncResp->res);
1632 },
1633 serviceName, objectPath, interfaceName, method);
1634 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001635};
1636
1637/**
Ed Tanous66173382018-08-15 18:20:59 -07001638 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001639 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001640class Systems : public Node
1641{
1642 public:
1643 /*
1644 * Default Constructor
1645 */
Ed Tanous029573d2019-02-01 10:57:49 -08001646 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001647 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001648 entityPrivileges = {
1649 {boost::beast::http::verb::get, {{"Login"}}},
1650 {boost::beast::http::verb::head, {{"Login"}}},
1651 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1652 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1653 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1654 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001655 }
1656
Ed Tanous1abe55e2018-09-05 08:30:59 -07001657 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001658 /**
1659 * Functions triggers appropriate requests on DBus
1660 */
1661 void doGet(crow::Response &res, const crow::Request &req,
1662 const std::vector<std::string> &params) override
1663 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301664 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001665 res.jsonValue["@odata.context"] =
1666 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001667 res.jsonValue["Name"] = "Computer System";
1668 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001669 res.jsonValue["SystemType"] = "Physical";
1670 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001671 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1672 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
1673 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
1674 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001675 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001676
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001677 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001678 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001679 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001680 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001681 res.jsonValue["Storage"] = {
1682 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001683
Ed Tanouscc340dd2018-08-29 13:43:38 -07001684 // TODO Need to support ForceRestart.
1685 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1686 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001687 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001688 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001689 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001690 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001691
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001692 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001693 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001694
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001695 res.jsonValue["Links"]["ManagedBy"] = {
1696 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1697
1698 res.jsonValue["Status"] = {
1699 {"Health", "OK"},
1700 {"State", "Enabled"},
1701 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001702 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001703
James Feist2ad9c2f2019-10-29 16:26:48 -07001704 constexpr const std::array<const char *, 3> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001705 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001706 "xyz.openbmc_project.Inventory.Item.Cpu",
1707 "xyz.openbmc_project.Inventory.Item.Drive"};
James Feistb49ac872019-05-21 15:12:01 -07001708
1709 auto health = std::make_shared<HealthPopulate>(asyncResp);
1710 crow::connections::systemBus->async_method_call(
1711 [health](const boost::system::error_code ec,
1712 std::vector<std::string> &resp) {
1713 if (ec)
1714 {
1715 // no inventory
1716 return;
1717 }
1718
1719 health->inventory = std::move(resp);
1720 },
1721 "xyz.openbmc_project.ObjectMapper",
1722 "/xyz/openbmc_project/object_mapper",
1723 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1724 int32_t(0), inventoryForSystems);
1725
1726 health->populate();
1727
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001728 getMainChassisId(asyncResp, [](const std::string &chassisId,
1729 std::shared_ptr<AsyncResp> aRsp) {
1730 aRsp->res.jsonValue["Links"]["Chassis"] = {
1731 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1732 });
AppaRao Pulia3002222019-11-12 21:32:59 +05301733
1734 getIndicatorLedState(asyncResp);
James Feist5bc2dc82019-10-22 14:33:16 -07001735 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001736 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301737 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001738 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001739 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301740#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1741 getProvisioningStatus(asyncResp);
1742#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001743 }
1744
Ed Tanous1abe55e2018-09-05 08:30:59 -07001745 void doPatch(crow::Response &res, const crow::Request &req,
1746 const std::vector<std::string> &params) override
1747 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301748 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301749 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001750 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001751 auto asyncResp = std::make_shared<AsyncResp>(res);
1752
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001753 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001754 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001755 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001756 return;
1757 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301758
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001759 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001760
1761 if (wdtTimerProps)
1762 {
1763 std::optional<bool> wdtEnable;
1764 std::optional<std::string> wdtTimeOutAction;
1765
1766 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1767 "FunctionEnabled", wdtEnable,
1768 "TimeoutAction", wdtTimeOutAction))
1769 {
1770 return;
1771 }
1772 setWDTProperties(asyncResp, std::move(wdtEnable),
1773 std::move(wdtTimeOutAction));
1774 }
1775
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301776 if (bootProps)
1777 {
1778 std::optional<std::string> bootSource;
1779 std::optional<std::string> bootEnable;
1780
1781 if (!json_util::readJson(*bootProps, asyncResp->res,
1782 "BootSourceOverrideTarget", bootSource,
1783 "BootSourceOverrideEnabled", bootEnable))
1784 {
1785 return;
1786 }
1787 setBootProperties(asyncResp, std::move(bootSource),
1788 std::move(bootEnable));
1789 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001790
Ed Tanous9712f8a2018-09-21 13:38:49 -07001791 if (indicatorLed)
1792 {
AppaRao Pulia3002222019-11-12 21:32:59 +05301793 setIndicatorLedState(asyncResp, std::move(*indicatorLed));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001794 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001795 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001796};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001797} // namespace redfish