blob: 0e6cb0941214dcdecc13365af8b2d59ad2c26f70 [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) {
AppaRao Pulif847a192019-11-15 14:57:44 +0530569 // Some systems may not have enclosure_identify_blink object so
570 // proceed to get enclosure_identify state.
571 if (!ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700572 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530573 const bool *blinking = std::get_if<bool>(&asserted);
574 if (!blinking)
575 {
576 BMCWEB_LOG_DEBUG << "Get identity blinking LED failed";
577 messages::internalError(aResp->res);
578 return;
579 }
580 // Blinking ON, no need to check enclosure_identify assert.
581 if (*blinking)
582 {
583 aResp->res.jsonValue["IndicatorLED"] = "Blinking";
584 return;
585 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530586 }
587 crow::connections::systemBus->async_method_call(
588 [aResp](const boost::system::error_code ec,
589 const std::variant<bool> asserted) {
AppaRao Pulif847a192019-11-15 14:57:44 +0530590 if (!ec)
Ed Tanous6c34de42018-08-29 13:37:36 -0700591 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530592 const bool *ledOn = std::get_if<bool>(&asserted);
593 if (!ledOn)
594 {
595 BMCWEB_LOG_DEBUG
596 << "Get enclosure identity led failed";
597 messages::internalError(aResp->res);
598 return;
599 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530600
AppaRao Pulif847a192019-11-15 14:57:44 +0530601 if (*ledOn)
602 {
603 aResp->res.jsonValue["IndicatorLED"] = "Lit";
604 }
605 else
606 {
607 aResp->res.jsonValue["IndicatorLED"] = "Off";
608 }
AppaRao Pulia3002222019-11-12 21:32:59 +0530609 }
610 return;
611 },
612 "xyz.openbmc_project.LED.GroupManager",
613 "/xyz/openbmc_project/led/groups/enclosure_identify",
614 "org.freedesktop.DBus.Properties", "Get",
615 "xyz.openbmc_project.Led.Group", "Asserted");
616 },
617 "xyz.openbmc_project.LED.GroupManager",
618 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
619 "org.freedesktop.DBus.Properties", "Get",
620 "xyz.openbmc_project.Led.Group", "Asserted");
621}
622/**
623 * @brief Sets identify led group properties
624 *
625 * @param[in] aResp Shared pointer for generating response message.
626 * @param[in] ledState LED state passed from request
627 *
628 * @return None.
629 */
630void setIndicatorLedState(std::shared_ptr<AsyncResp> aResp,
631 const std::string &ledState)
632{
633 BMCWEB_LOG_DEBUG << "Set led groups";
634 bool ledOn = false;
635 bool ledBlinkng = false;
636
637 if (ledState == "Lit")
638 {
639 ledOn = true;
640 }
641 else if (ledState == "Blinking")
642 {
643 ledBlinkng = true;
644 }
645 else if (ledState != "Off")
646 {
647 messages::propertyValueNotInList(aResp->res, ledState, "IndicatorLED");
648 return;
649 }
650
651 crow::connections::systemBus->async_method_call(
AppaRao Pulif847a192019-11-15 14:57:44 +0530652 [aResp, ledOn, ledBlinkng](const boost::system::error_code ec,
653 const std::variant<bool> asserted) mutable {
AppaRao Pulia3002222019-11-12 21:32:59 +0530654 if (ec)
655 {
AppaRao Pulif847a192019-11-15 14:57:44 +0530656 // Some systems may not have enclosure_identify_blink object so
657 // Lets set enclosure_identify state to true if Blinking is
658 // true.
659 if (ledBlinkng)
660 {
661 ledOn = true;
662 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700663 }
AppaRao Pulif847a192019-11-15 14:57:44 +0530664 crow::connections::systemBus->async_method_call(
665 [aResp](const boost::system::error_code ec,
666 const std::variant<bool> asserted) {
667 if (ec)
668 {
669 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
670 messages::internalError(aResp->res);
671 return;
672 }
673 },
674 "xyz.openbmc_project.LED.GroupManager",
675 "/xyz/openbmc_project/led/groups/enclosure_identify",
676 "org.freedesktop.DBus.Properties", "Set",
677 "xyz.openbmc_project.Led.Group", "Asserted",
678 std::variant<bool>(ledOn));
AppaRao Pulia3002222019-11-12 21:32:59 +0530679 },
680 "xyz.openbmc_project.LED.GroupManager",
681 "/xyz/openbmc_project/led/groups/enclosure_identify_blink",
682 "org.freedesktop.DBus.Properties", "Set",
683 "xyz.openbmc_project.Led.Group", "Asserted",
684 std::variant<bool>(ledBlinkng));
Ed Tanous6c34de42018-08-29 13:37:36 -0700685}
686
Ed Tanous6c34de42018-08-29 13:37:36 -0700687/**
688 * @brief Retrieves host state properties over dbus
689 *
690 * @param[in] aResp Shared pointer for completing asynchronous calls.
691 *
692 * @return None.
693 */
694void getHostState(std::shared_ptr<AsyncResp> aResp)
695{
696 BMCWEB_LOG_DEBUG << "Get host information.";
697 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800698 [aResp](const boost::system::error_code ec,
699 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700700 if (ec)
701 {
702 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700703 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700704 return;
705 }
Ed Tanous66173382018-08-15 18:20:59 -0700706
Ed Tanousabf2add2019-01-22 16:40:12 -0800707 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700708 BMCWEB_LOG_DEBUG << "Host state: " << *s;
709 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700710 {
Ed Tanous66173382018-08-15 18:20:59 -0700711 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800712 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700713 {
Ed Tanous66173382018-08-15 18:20:59 -0700714 aResp->res.jsonValue["PowerState"] = "On";
715 aResp->res.jsonValue["Status"]["State"] = "Enabled";
716 }
717 else
718 {
719 aResp->res.jsonValue["PowerState"] = "Off";
720 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700721 }
722 }
723 },
724 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700725 "org.freedesktop.DBus.Properties", "Get",
726 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700727}
728
729/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530730 * @brief Traslates boot source DBUS property value to redfish.
731 *
732 * @param[in] dbusSource The boot source in DBUS speak.
733 *
734 * @return Returns as a string, the boot source in Redfish terms. If translation
735 * cannot be done, returns an empty string.
736 */
737static std::string dbusToRfBootSource(const std::string &dbusSource)
738{
739 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
740 {
741 return "None";
742 }
743 else if (dbusSource ==
744 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
745 {
746 return "Hdd";
747 }
748 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530749 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530750 {
751 return "Cd";
752 }
753 else if (dbusSource ==
754 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
755 {
756 return "Pxe";
757 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700758 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700759 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700760 {
761 return "Usb";
762 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530763 else
764 {
765 return "";
766 }
767}
768
769/**
770 * @brief Traslates boot mode DBUS property value to redfish.
771 *
772 * @param[in] dbusMode The boot mode in DBUS speak.
773 *
774 * @return Returns as a string, the boot mode in Redfish terms. If translation
775 * cannot be done, returns an empty string.
776 */
777static std::string dbusToRfBootMode(const std::string &dbusMode)
778{
779 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
780 {
781 return "None";
782 }
783 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
784 {
785 return "Diags";
786 }
787 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
788 {
789 return "BiosSetup";
790 }
791 else
792 {
793 return "";
794 }
795}
796
797/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700798 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530799 *
800 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700801 * @param[out] bootSource The DBus source
802 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530803 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700804 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530805 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700806static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
807 const std::string &rfSource,
808 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530809{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700810 // The caller has initialized the bootSource and bootMode to:
811 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
812 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
813 // Only modify the bootSource/bootMode variable needed to achieve the
814 // desired boot action.
815
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530816 if (rfSource == "None")
817 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700818 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530819 }
820 else if (rfSource == "Pxe")
821 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700822 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
823 }
824 else if (rfSource == "Hdd")
825 {
826 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
827 }
828 else if (rfSource == "Diags")
829 {
830 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
831 }
832 else if (rfSource == "Cd")
833 {
834 bootSource =
835 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
836 }
837 else if (rfSource == "BiosSetup")
838 {
839 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530840 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700841 else if (rfSource == "Usb")
842 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700843 bootSource =
844 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700845 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530846 else
847 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700848 BMCWEB_LOG_DEBUG << "Invalid property value for "
849 "BootSourceOverrideTarget: "
850 << bootSource;
851 messages::propertyValueNotInList(aResp->res, rfSource,
852 "BootSourceTargetOverride");
853 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530854 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700855 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530856}
857
858/**
859 * @brief Retrieves boot mode over DBUS and fills out the response
860 *
861 * @param[in] aResp Shared pointer for generating response message.
862 * @param[in] bootDbusObj The dbus object to query for boot properties.
863 *
864 * @return None.
865 */
866static void getBootMode(std::shared_ptr<AsyncResp> aResp,
867 std::string bootDbusObj)
868{
869 crow::connections::systemBus->async_method_call(
870 [aResp](const boost::system::error_code ec,
871 const std::variant<std::string> &bootMode) {
872 if (ec)
873 {
874 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
875 messages::internalError(aResp->res);
876 return;
877 }
878
879 const std::string *bootModeStr =
880 std::get_if<std::string>(&bootMode);
881
882 if (!bootModeStr)
883 {
884 messages::internalError(aResp->res);
885 return;
886 }
887
888 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
889
890 // TODO (Santosh): Do we need to support override mode?
891 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
892 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
893 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700894 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530895
896 if (*bootModeStr !=
897 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
898 {
899 auto rfMode = dbusToRfBootMode(*bootModeStr);
900 if (!rfMode.empty())
901 {
902 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
903 rfMode;
904 }
905 }
906
907 // If the BootSourceOverrideTarget is still "None" at the end,
908 // reset the BootSourceOverrideEnabled to indicate that
909 // overrides are disabled
910 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
911 "None")
912 {
913 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
914 "Disabled";
915 }
916 },
917 "xyz.openbmc_project.Settings", bootDbusObj,
918 "org.freedesktop.DBus.Properties", "Get",
919 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
920}
921
922/**
923 * @brief Retrieves boot source over DBUS
924 *
925 * @param[in] aResp Shared pointer for generating response message.
926 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
927 *
928 * @return None.
929 */
930static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
931{
932 std::string bootDbusObj =
933 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
934 : "/xyz/openbmc_project/control/host0/boot";
935
936 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
937 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
938 (oneTimeEnabled) ? "Once" : "Continuous";
939
940 crow::connections::systemBus->async_method_call(
941 [aResp, bootDbusObj](const boost::system::error_code ec,
942 const std::variant<std::string> &bootSource) {
943 if (ec)
944 {
945 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
946 messages::internalError(aResp->res);
947 return;
948 }
949
950 const std::string *bootSourceStr =
951 std::get_if<std::string>(&bootSource);
952
953 if (!bootSourceStr)
954 {
955 messages::internalError(aResp->res);
956 return;
957 }
958 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
959
960 auto rfSource = dbusToRfBootSource(*bootSourceStr);
961 if (!rfSource.empty())
962 {
963 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
964 rfSource;
965 }
966 },
967 "xyz.openbmc_project.Settings", bootDbusObj,
968 "org.freedesktop.DBus.Properties", "Get",
969 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
970 getBootMode(std::move(aResp), std::move(bootDbusObj));
971}
972
973/**
974 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
975 * get boot source and boot mode.
976 *
977 * @param[in] aResp Shared pointer for generating response message.
978 *
979 * @return None.
980 */
981static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
982{
983 BMCWEB_LOG_DEBUG << "Get boot information.";
984
985 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800986 [aResp](const boost::system::error_code ec,
987 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530988 if (ec)
989 {
990 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700991 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530992 return;
993 }
994
995 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
996
997 if (!oneTimePtr)
998 {
999 messages::internalError(aResp->res);
1000 return;
1001 }
1002 getBootSource(aResp, *oneTimePtr);
1003 },
1004 "xyz.openbmc_project.Settings",
1005 "/xyz/openbmc_project/control/host0/boot/one_time",
1006 "org.freedesktop.DBus.Properties", "Get",
1007 "xyz.openbmc_project.Object.Enable", "Enabled");
1008}
1009
1010/**
1011 * @brief Sets boot properties into DBUS object(s).
1012 *
1013 * @param[in] aResp Shared pointer for generating response message.
1014 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
1015 * @param[in] bootSource The boot source to set.
1016 * @param[in] bootEnable The source override "enable" to set.
1017 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001018 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301019 */
1020static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1021 bool oneTimeEnabled,
1022 std::optional<std::string> bootSource,
1023 std::optional<std::string> bootEnable)
1024{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001025 std::string bootSourceStr =
1026 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1027 std::string bootModeStr =
1028 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301029 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001030 bool useBootSource = true;
1031
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301032 // Validate incoming parameters
1033 if (bootEnable)
1034 {
1035 if (*bootEnable == "Once")
1036 {
1037 oneTimeSetting = true;
1038 }
1039 else if (*bootEnable == "Continuous")
1040 {
1041 oneTimeSetting = false;
1042 }
1043 else if (*bootEnable == "Disabled")
1044 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001045 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301046 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001047 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301048 }
1049 else
1050 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301051 BMCWEB_LOG_DEBUG << "Unsupported value for "
1052 "BootSourceOverrideEnabled: "
1053 << *bootEnable;
1054 messages::propertyValueNotInList(aResp->res, *bootEnable,
1055 "BootSourceOverrideEnabled");
1056 return;
1057 }
1058 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301059
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001060 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301061 {
1062 // Source target specified
1063 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1064 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001065 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1066 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301067 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001068 BMCWEB_LOG_DEBUG
1069 << "Invalid property value for BootSourceOverrideTarget: "
1070 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301071 messages::propertyValueNotInList(aResp->res, *bootSource,
1072 "BootSourceTargetOverride");
1073 return;
1074 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001075 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301076
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001077 // Act on validated parameters
1078 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1079 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1080 const char *bootObj =
1081 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1082 : "/xyz/openbmc_project/control/host0/boot";
1083
1084 crow::connections::systemBus->async_method_call(
1085 [aResp](const boost::system::error_code ec) {
1086 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301087 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001088 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1089 messages::internalError(aResp->res);
1090 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301091 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001092 BMCWEB_LOG_DEBUG << "Boot source update done.";
1093 },
1094 "xyz.openbmc_project.Settings", bootObj,
1095 "org.freedesktop.DBus.Properties", "Set",
1096 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1097 std::variant<std::string>(bootSourceStr));
1098
1099 crow::connections::systemBus->async_method_call(
1100 [aResp](const boost::system::error_code ec) {
1101 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301102 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001103 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1104 messages::internalError(aResp->res);
1105 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301106 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001107 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1108 },
1109 "xyz.openbmc_project.Settings", bootObj,
1110 "org.freedesktop.DBus.Properties", "Set",
1111 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1112 std::variant<std::string>(bootModeStr));
1113
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301114 crow::connections::systemBus->async_method_call(
1115 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1116 if (ec)
1117 {
1118 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1119 messages::internalError(aResp->res);
1120 return;
1121 }
1122 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1123 },
1124 "xyz.openbmc_project.Settings",
1125 "/xyz/openbmc_project/control/host0/boot/one_time",
1126 "org.freedesktop.DBus.Properties", "Set",
1127 "xyz.openbmc_project.Object.Enable", "Enabled",
1128 std::variant<bool>(oneTimeSetting));
1129}
1130
1131/**
1132 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1133 * set boot source/boot mode properties.
1134 *
1135 * @param[in] aResp Shared pointer for generating response message.
1136 * @param[in] bootSource The boot source from incoming RF request.
1137 * @param[in] bootEnable The boot override enable from incoming RF request.
1138 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001139 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301140 */
1141static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1142 std::optional<std::string> bootSource,
1143 std::optional<std::string> bootEnable)
1144{
1145 BMCWEB_LOG_DEBUG << "Set boot information.";
1146
1147 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001148 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301149 bootEnable{std::move(bootEnable)}](
1150 const boost::system::error_code ec,
1151 const sdbusplus::message::variant<bool> &oneTime) {
1152 if (ec)
1153 {
1154 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1155 messages::internalError(aResp->res);
1156 return;
1157 }
1158
1159 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1160
1161 if (!oneTimePtr)
1162 {
1163 messages::internalError(aResp->res);
1164 return;
1165 }
1166
1167 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1168
1169 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1170 std::move(bootEnable));
1171 },
1172 "xyz.openbmc_project.Settings",
1173 "/xyz/openbmc_project/control/host0/boot/one_time",
1174 "org.freedesktop.DBus.Properties", "Get",
1175 "xyz.openbmc_project.Object.Enable", "Enabled");
1176}
1177
AppaRao Pulia6349912019-10-18 17:16:08 +05301178#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1179/**
1180 * @brief Retrieves provisioning status
1181 *
1182 * @param[in] aResp Shared pointer for completing asynchronous calls.
1183 *
1184 * @return None.
1185 */
1186void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1187{
1188 BMCWEB_LOG_DEBUG << "Get OEM information.";
1189 crow::connections::systemBus->async_method_call(
1190 [aResp](const boost::system::error_code ec,
1191 const std::vector<std::pair<std::string, VariantType>>
1192 &propertiesList) {
1193 if (ec)
1194 {
1195 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1196 messages::internalError(aResp->res);
1197 return;
1198 }
1199
1200 const bool *provState = nullptr;
1201 const bool *lockState = nullptr;
1202 for (const std::pair<std::string, VariantType> &property :
1203 propertiesList)
1204 {
1205 if (property.first == "UfmProvisioned")
1206 {
1207 provState = std::get_if<bool>(&property.second);
1208 }
1209 else if (property.first == "UfmLocked")
1210 {
1211 lockState = std::get_if<bool>(&property.second);
1212 }
1213 }
1214
1215 if ((provState == nullptr) || (lockState == nullptr))
1216 {
1217 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1218 messages::internalError(aResp->res);
1219 return;
1220 }
1221
1222 nlohmann::json &oemPFR =
1223 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1224 if (*provState == true)
1225 {
1226 if (*lockState == true)
1227 {
1228 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1229 }
1230 else
1231 {
1232 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1233 }
1234 }
1235 else
1236 {
1237 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1238 }
1239 },
1240 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1241 "org.freedesktop.DBus.Properties", "GetAll",
1242 "xyz.openbmc_project.PFR.Attributes");
1243}
1244#endif
1245
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301246/**
Yong Li51709ff2019-09-30 14:13:04 +08001247 * @brief Translates watchdog timeout action DBUS property value to redfish.
1248 *
1249 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1250 *
1251 * @return Returns as a string, the timeout action in Redfish terms. If
1252 * translation cannot be done, returns an empty string.
1253 */
1254static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1255{
1256 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1257 {
1258 return "None";
1259 }
1260 else if (dbusAction ==
1261 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1262 {
1263 return "ResetSystem";
1264 }
1265 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1266 {
1267 return "PowerDown";
1268 }
1269 else if (dbusAction ==
1270 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1271 {
1272 return "PowerCycle";
1273 }
1274
1275 return "";
1276}
1277
1278/**
Yong Lic45f0082019-10-10 14:19:01 +08001279 *@brief Translates timeout action from Redfish to DBUS property value.
1280 *
1281 *@param[in] rfAction The timeout action in Redfish.
1282 *
1283 *@return Returns as a string, the time_out action as expected by DBUS.
1284 *If translation cannot be done, returns an empty string.
1285 */
1286
1287static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1288{
1289 if (rfAction == "None")
1290 {
1291 return "xyz.openbmc_project.State.Watchdog.Action.None";
1292 }
1293 else if (rfAction == "PowerCycle")
1294 {
1295 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1296 }
1297 else if (rfAction == "PowerDown")
1298 {
1299 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1300 }
1301 else if (rfAction == "ResetSystem")
1302 {
1303 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1304 }
1305
1306 return "";
1307}
1308
1309/**
Yong Li51709ff2019-09-30 14:13:04 +08001310 * @brief Retrieves host watchdog timer properties over DBUS
1311 *
1312 * @param[in] aResp Shared pointer for completing asynchronous calls.
1313 *
1314 * @return None.
1315 */
1316void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1317{
1318 BMCWEB_LOG_DEBUG << "Get host watchodg";
1319 crow::connections::systemBus->async_method_call(
1320 [aResp](const boost::system::error_code ec,
1321 PropertiesType &properties) {
1322 if (ec)
1323 {
1324 // watchdog service is stopped
1325 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1326 return;
1327 }
1328
1329 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1330
1331 nlohmann::json &hostWatchdogTimer =
1332 aResp->res.jsonValue["HostWatchdogTimer"];
1333
1334 // watchdog service is running/enabled
1335 hostWatchdogTimer["Status"]["State"] = "Enabled";
1336
1337 for (const auto &property : properties)
1338 {
1339 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1340 if (property.first == "Enabled")
1341 {
1342 const bool *state = std::get_if<bool>(&property.second);
1343
1344 if (!state)
1345 {
1346 messages::internalError(aResp->res);
1347 continue;
1348 }
1349
1350 hostWatchdogTimer["FunctionEnabled"] = *state;
1351 }
1352 else if (property.first == "ExpireAction")
1353 {
1354 const std::string *s =
1355 std::get_if<std::string>(&property.second);
1356 if (!s)
1357 {
1358 messages::internalError(aResp->res);
1359 continue;
1360 }
1361
1362 std::string action = dbusToRfWatchdogAction(*s);
1363 if (action.empty())
1364 {
1365 messages::internalError(aResp->res);
1366 continue;
1367 }
1368 hostWatchdogTimer["TimeoutAction"] = action;
1369 }
1370 }
1371 },
1372 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1373 "org.freedesktop.DBus.Properties", "GetAll",
1374 "xyz.openbmc_project.State.Watchdog");
1375}
1376
1377/**
Yong Lic45f0082019-10-10 14:19:01 +08001378 * @brief Sets Host WatchDog Timer properties.
1379 *
1380 * @param[in] aResp Shared pointer for generating response message.
1381 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1382 * RF request.
1383 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1384 *
1385 * @return None.
1386 */
1387static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1388 const std::optional<bool> wdtEnable,
1389 const std::optional<std::string> &wdtTimeOutAction)
1390{
1391 BMCWEB_LOG_DEBUG << "Set host watchdog";
1392
1393 if (wdtTimeOutAction)
1394 {
1395 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1396 // check if TimeOut Action is Valid
1397 if (wdtTimeOutActStr.empty())
1398 {
1399 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1400 << *wdtTimeOutAction;
1401 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1402 "TimeoutAction");
1403 return;
1404 }
1405
1406 crow::connections::systemBus->async_method_call(
1407 [aResp](const boost::system::error_code ec) {
1408 if (ec)
1409 {
1410 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1411 messages::internalError(aResp->res);
1412 return;
1413 }
1414 },
1415 "xyz.openbmc_project.Watchdog",
1416 "/xyz/openbmc_project/watchdog/host0",
1417 "org.freedesktop.DBus.Properties", "Set",
1418 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1419 std::variant<std::string>(wdtTimeOutActStr));
1420 }
1421
1422 if (wdtEnable)
1423 {
1424 crow::connections::systemBus->async_method_call(
1425 [aResp](const boost::system::error_code ec) {
1426 if (ec)
1427 {
1428 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1429 messages::internalError(aResp->res);
1430 return;
1431 }
1432 },
1433 "xyz.openbmc_project.Watchdog",
1434 "/xyz/openbmc_project/watchdog/host0",
1435 "org.freedesktop.DBus.Properties", "Set",
1436 "xyz.openbmc_project.State.Watchdog", "Enabled",
1437 std::variant<bool>(*wdtEnable));
1438 }
1439}
1440
1441/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001442 * SystemsCollection derived class for delivering ComputerSystems Collection
1443 * Schema
1444 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001445class SystemsCollection : public Node
1446{
1447 public:
1448 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1449 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001450 entityPrivileges = {
1451 {boost::beast::http::verb::get, {{"Login"}}},
1452 {boost::beast::http::verb::head, {{"Login"}}},
1453 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1454 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1455 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1456 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1457 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001458
Ed Tanous1abe55e2018-09-05 08:30:59 -07001459 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001460 void doGet(crow::Response &res, const crow::Request &req,
1461 const std::vector<std::string> &params) override
1462 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001463 res.jsonValue["@odata.type"] =
1464 "#ComputerSystemCollection.ComputerSystemCollection";
1465 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1466 res.jsonValue["@odata.context"] =
1467 "/redfish/v1/"
1468 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1469 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001470 res.jsonValue["Members"] = {
1471 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1472 res.jsonValue["Members@odata.count"] = 1;
1473 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001474 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001475};
1476
1477/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001478 * SystemActionsReset class supports handle POST method for Reset action.
1479 * The class retrieves and sends data directly to D-Bus.
1480 */
1481class SystemActionsReset : public Node
1482{
1483 public:
1484 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001485 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001486 {
1487 entityPrivileges = {
1488 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1489 }
1490
1491 private:
1492 /**
1493 * Function handles POST method request.
1494 * Analyzes POST body message before sends Reset request data to D-Bus.
1495 */
1496 void doPost(crow::Response &res, const crow::Request &req,
1497 const std::vector<std::string> &params) override
1498 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001499 auto asyncResp = std::make_shared<AsyncResp>(res);
1500
1501 std::string resetType;
1502 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001503 {
1504 return;
1505 }
1506
Jason M. Billsd22c8392019-06-03 13:59:03 -07001507 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001508 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001509 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001510 if (resetType == "On")
1511 {
1512 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001513 hostCommand = true;
1514 }
1515 else if (resetType == "ForceOff")
1516 {
1517 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1518 hostCommand = false;
1519 }
1520 else if (resetType == "ForceOn")
1521 {
1522 command = "xyz.openbmc_project.State.Host.Transition.On";
1523 hostCommand = true;
1524 }
1525 else if (resetType == "ForceRestart")
1526 {
1527 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1528 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001529 }
1530 else if (resetType == "GracefulShutdown")
1531 {
1532 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001533 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001534 }
1535 else if (resetType == "GracefulRestart")
1536 {
1537 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001538 hostCommand = true;
1539 }
1540 else if (resetType == "PowerCycle")
1541 {
1542 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1543 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001544 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001545 else if (resetType == "Nmi")
1546 {
1547 doNMI(asyncResp);
1548 return;
1549 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001550 else
1551 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001552 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001553 return;
1554 }
1555
Jason M. Billsd22c8392019-06-03 13:59:03 -07001556 if (hostCommand)
1557 {
1558 crow::connections::systemBus->async_method_call(
1559 [asyncResp, resetType](const boost::system::error_code ec) {
1560 if (ec)
1561 {
1562 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1563 if (ec.value() == boost::asio::error::invalid_argument)
1564 {
1565 messages::actionParameterNotSupported(
1566 asyncResp->res, resetType, "Reset");
1567 }
1568 else
1569 {
1570 messages::internalError(asyncResp->res);
1571 }
1572 return;
1573 }
1574 messages::success(asyncResp->res);
1575 },
1576 "xyz.openbmc_project.State.Host",
1577 "/xyz/openbmc_project/state/host0",
1578 "org.freedesktop.DBus.Properties", "Set",
1579 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1580 std::variant<std::string>{command});
1581 }
1582 else
1583 {
1584 crow::connections::systemBus->async_method_call(
1585 [asyncResp, resetType](const boost::system::error_code ec) {
1586 if (ec)
1587 {
1588 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1589 if (ec.value() == boost::asio::error::invalid_argument)
1590 {
1591 messages::actionParameterNotSupported(
1592 asyncResp->res, resetType, "Reset");
1593 }
1594 else
1595 {
1596 messages::internalError(asyncResp->res);
1597 }
1598 return;
1599 }
1600 messages::success(asyncResp->res);
1601 },
1602 "xyz.openbmc_project.State.Chassis",
1603 "/xyz/openbmc_project/state/chassis0",
1604 "org.freedesktop.DBus.Properties", "Set",
1605 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1606 std::variant<std::string>{command});
1607 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001608 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001609 /**
1610 * Function transceives data with dbus directly.
1611 */
1612 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1613 {
1614 constexpr char const *serviceName =
1615 "xyz.openbmc_project.Control.Host.NMI";
1616 constexpr char const *objectPath =
1617 "/xyz/openbmc_project/control/host0/nmi";
1618 constexpr char const *interfaceName =
1619 "xyz.openbmc_project.Control.Host.NMI";
1620 constexpr char const *method = "NMI";
1621
1622 crow::connections::systemBus->async_method_call(
1623 [asyncResp](const boost::system::error_code ec) {
1624 if (ec)
1625 {
1626 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1627 messages::internalError(asyncResp->res);
1628 return;
1629 }
1630 messages::success(asyncResp->res);
1631 },
1632 serviceName, objectPath, interfaceName, method);
1633 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001634};
1635
1636/**
Ed Tanous66173382018-08-15 18:20:59 -07001637 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001638 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001639class Systems : public Node
1640{
1641 public:
1642 /*
1643 * Default Constructor
1644 */
Ed Tanous029573d2019-02-01 10:57:49 -08001645 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001646 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001647 entityPrivileges = {
1648 {boost::beast::http::verb::get, {{"Login"}}},
1649 {boost::beast::http::verb::head, {{"Login"}}},
1650 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1651 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1652 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1653 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001654 }
1655
Ed Tanous1abe55e2018-09-05 08:30:59 -07001656 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001657 /**
1658 * Functions triggers appropriate requests on DBus
1659 */
1660 void doGet(crow::Response &res, const crow::Request &req,
1661 const std::vector<std::string> &params) override
1662 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301663 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001664 res.jsonValue["@odata.context"] =
1665 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001666 res.jsonValue["Name"] = "Computer System";
1667 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001668 res.jsonValue["SystemType"] = "Physical";
1669 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001670 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1671 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
1672 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
1673 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001674 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001675
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001676 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001677 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001678 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001679 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001680 res.jsonValue["Storage"] = {
1681 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001682
Ed Tanouscc340dd2018-08-29 13:43:38 -07001683 // TODO Need to support ForceRestart.
1684 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1685 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001686 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001687 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001688 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001689 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001690
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001691 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001692 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001693
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001694 res.jsonValue["Links"]["ManagedBy"] = {
1695 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1696
1697 res.jsonValue["Status"] = {
1698 {"Health", "OK"},
1699 {"State", "Enabled"},
1700 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001701 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001702
James Feiste284a7c2019-11-20 16:20:23 -08001703 constexpr const std::array<const char *, 4> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001704 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001705 "xyz.openbmc_project.Inventory.Item.Cpu",
James Feiste284a7c2019-11-20 16:20:23 -08001706 "xyz.openbmc_project.Inventory.Item.Drive",
1707 "xyz.openbmc_project.Inventory.Item.StorageController"};
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