blob: 707eca90d0e02225b02d8bb1269436e430a31168 [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 * @param[in] callback Callback for process retrieved data.
561 *
562 * @return None.
563 */
564template <typename CallbackFunc>
565void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
566 CallbackFunc &&callback)
567{
568 BMCWEB_LOG_DEBUG << "Get led groups";
569 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800570 [aResp,
Ed Tanous66173382018-08-15 18:20:59 -0700571 callback{std::move(callback)}](const boost::system::error_code &ec,
572 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700573 if (ec)
574 {
575 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700576 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700577 return;
578 }
Gunnar Mills698654b2019-10-16 13:17:37 -0500579 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " led group objects.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700580 for (const auto &objPath : resp)
581 {
582 const std::string &path = objPath.first;
583 if (path.rfind("enclosure_identify") != std::string::npos)
584 {
585 for (const auto &interface : objPath.second)
586 {
587 if (interface.first == "xyz.openbmc_project.Led.Group")
588 {
589 for (const auto &property : interface.second)
590 {
591 if (property.first == "Asserted")
592 {
593 const bool *asserted =
Ed Tanousabf2add2019-01-22 16:40:12 -0800594 std::get_if<bool>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700595 if (nullptr != asserted)
596 {
597 callback(*asserted, aResp);
598 }
599 else
600 {
601 callback(false, aResp);
602 }
603 }
604 }
605 }
606 }
607 }
608 }
609 },
610 "xyz.openbmc_project.LED.GroupManager",
611 "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
612 "GetManagedObjects");
613}
614
Ed Tanous6c34de42018-08-29 13:37:36 -0700615/**
616 * @brief Retrieves host state properties over dbus
617 *
618 * @param[in] aResp Shared pointer for completing asynchronous calls.
619 *
620 * @return None.
621 */
622void getHostState(std::shared_ptr<AsyncResp> aResp)
623{
624 BMCWEB_LOG_DEBUG << "Get host information.";
625 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800626 [aResp](const boost::system::error_code ec,
627 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700628 if (ec)
629 {
630 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700631 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700632 return;
633 }
Ed Tanous66173382018-08-15 18:20:59 -0700634
Ed Tanousabf2add2019-01-22 16:40:12 -0800635 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700636 BMCWEB_LOG_DEBUG << "Host state: " << *s;
637 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700638 {
Ed Tanous66173382018-08-15 18:20:59 -0700639 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800640 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700641 {
Ed Tanous66173382018-08-15 18:20:59 -0700642 aResp->res.jsonValue["PowerState"] = "On";
643 aResp->res.jsonValue["Status"]["State"] = "Enabled";
644 }
645 else
646 {
647 aResp->res.jsonValue["PowerState"] = "Off";
648 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700649 }
650 }
651 },
652 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700653 "org.freedesktop.DBus.Properties", "Get",
654 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700655}
656
657/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530658 * @brief Traslates boot source DBUS property value to redfish.
659 *
660 * @param[in] dbusSource The boot source in DBUS speak.
661 *
662 * @return Returns as a string, the boot source in Redfish terms. If translation
663 * cannot be done, returns an empty string.
664 */
665static std::string dbusToRfBootSource(const std::string &dbusSource)
666{
667 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
668 {
669 return "None";
670 }
671 else if (dbusSource ==
672 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
673 {
674 return "Hdd";
675 }
676 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530677 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530678 {
679 return "Cd";
680 }
681 else if (dbusSource ==
682 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
683 {
684 return "Pxe";
685 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700686 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700687 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700688 {
689 return "Usb";
690 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530691 else
692 {
693 return "";
694 }
695}
696
697/**
698 * @brief Traslates boot mode DBUS property value to redfish.
699 *
700 * @param[in] dbusMode The boot mode in DBUS speak.
701 *
702 * @return Returns as a string, the boot mode in Redfish terms. If translation
703 * cannot be done, returns an empty string.
704 */
705static std::string dbusToRfBootMode(const std::string &dbusMode)
706{
707 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
708 {
709 return "None";
710 }
711 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
712 {
713 return "Diags";
714 }
715 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
716 {
717 return "BiosSetup";
718 }
719 else
720 {
721 return "";
722 }
723}
724
725/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700726 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530727 *
728 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700729 * @param[out] bootSource The DBus source
730 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530731 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700732 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530733 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700734static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
735 const std::string &rfSource,
736 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530737{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700738 // The caller has initialized the bootSource and bootMode to:
739 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
740 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
741 // Only modify the bootSource/bootMode variable needed to achieve the
742 // desired boot action.
743
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530744 if (rfSource == "None")
745 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700746 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530747 }
748 else if (rfSource == "Pxe")
749 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700750 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
751 }
752 else if (rfSource == "Hdd")
753 {
754 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
755 }
756 else if (rfSource == "Diags")
757 {
758 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
759 }
760 else if (rfSource == "Cd")
761 {
762 bootSource =
763 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
764 }
765 else if (rfSource == "BiosSetup")
766 {
767 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530768 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700769 else if (rfSource == "Usb")
770 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700771 bootSource =
772 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700773 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530774 else
775 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700776 BMCWEB_LOG_DEBUG << "Invalid property value for "
777 "BootSourceOverrideTarget: "
778 << bootSource;
779 messages::propertyValueNotInList(aResp->res, rfSource,
780 "BootSourceTargetOverride");
781 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530782 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700783 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530784}
785
786/**
787 * @brief Retrieves boot mode over DBUS and fills out the response
788 *
789 * @param[in] aResp Shared pointer for generating response message.
790 * @param[in] bootDbusObj The dbus object to query for boot properties.
791 *
792 * @return None.
793 */
794static void getBootMode(std::shared_ptr<AsyncResp> aResp,
795 std::string bootDbusObj)
796{
797 crow::connections::systemBus->async_method_call(
798 [aResp](const boost::system::error_code ec,
799 const std::variant<std::string> &bootMode) {
800 if (ec)
801 {
802 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
803 messages::internalError(aResp->res);
804 return;
805 }
806
807 const std::string *bootModeStr =
808 std::get_if<std::string>(&bootMode);
809
810 if (!bootModeStr)
811 {
812 messages::internalError(aResp->res);
813 return;
814 }
815
816 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
817
818 // TODO (Santosh): Do we need to support override mode?
819 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
820 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
821 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700822 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530823
824 if (*bootModeStr !=
825 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
826 {
827 auto rfMode = dbusToRfBootMode(*bootModeStr);
828 if (!rfMode.empty())
829 {
830 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
831 rfMode;
832 }
833 }
834
835 // If the BootSourceOverrideTarget is still "None" at the end,
836 // reset the BootSourceOverrideEnabled to indicate that
837 // overrides are disabled
838 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
839 "None")
840 {
841 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
842 "Disabled";
843 }
844 },
845 "xyz.openbmc_project.Settings", bootDbusObj,
846 "org.freedesktop.DBus.Properties", "Get",
847 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
848}
849
850/**
851 * @brief Retrieves boot source over DBUS
852 *
853 * @param[in] aResp Shared pointer for generating response message.
854 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
855 *
856 * @return None.
857 */
858static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
859{
860 std::string bootDbusObj =
861 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
862 : "/xyz/openbmc_project/control/host0/boot";
863
864 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
865 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
866 (oneTimeEnabled) ? "Once" : "Continuous";
867
868 crow::connections::systemBus->async_method_call(
869 [aResp, bootDbusObj](const boost::system::error_code ec,
870 const std::variant<std::string> &bootSource) {
871 if (ec)
872 {
873 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
874 messages::internalError(aResp->res);
875 return;
876 }
877
878 const std::string *bootSourceStr =
879 std::get_if<std::string>(&bootSource);
880
881 if (!bootSourceStr)
882 {
883 messages::internalError(aResp->res);
884 return;
885 }
886 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
887
888 auto rfSource = dbusToRfBootSource(*bootSourceStr);
889 if (!rfSource.empty())
890 {
891 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
892 rfSource;
893 }
894 },
895 "xyz.openbmc_project.Settings", bootDbusObj,
896 "org.freedesktop.DBus.Properties", "Get",
897 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
898 getBootMode(std::move(aResp), std::move(bootDbusObj));
899}
900
901/**
902 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
903 * get boot source and boot mode.
904 *
905 * @param[in] aResp Shared pointer for generating response message.
906 *
907 * @return None.
908 */
909static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
910{
911 BMCWEB_LOG_DEBUG << "Get boot information.";
912
913 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800914 [aResp](const boost::system::error_code ec,
915 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530916 if (ec)
917 {
918 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700919 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530920 return;
921 }
922
923 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
924
925 if (!oneTimePtr)
926 {
927 messages::internalError(aResp->res);
928 return;
929 }
930 getBootSource(aResp, *oneTimePtr);
931 },
932 "xyz.openbmc_project.Settings",
933 "/xyz/openbmc_project/control/host0/boot/one_time",
934 "org.freedesktop.DBus.Properties", "Get",
935 "xyz.openbmc_project.Object.Enable", "Enabled");
936}
937
938/**
939 * @brief Sets boot properties into DBUS object(s).
940 *
941 * @param[in] aResp Shared pointer for generating response message.
942 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
943 * @param[in] bootSource The boot source to set.
944 * @param[in] bootEnable The source override "enable" to set.
945 *
Johnathan Mantey265c1602019-08-08 11:02:51 -0700946 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530947 */
948static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
949 bool oneTimeEnabled,
950 std::optional<std::string> bootSource,
951 std::optional<std::string> bootEnable)
952{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700953 std::string bootSourceStr =
954 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
955 std::string bootModeStr =
956 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530957 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700958 bool useBootSource = true;
959
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530960 // Validate incoming parameters
961 if (bootEnable)
962 {
963 if (*bootEnable == "Once")
964 {
965 oneTimeSetting = true;
966 }
967 else if (*bootEnable == "Continuous")
968 {
969 oneTimeSetting = false;
970 }
971 else if (*bootEnable == "Disabled")
972 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700973 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700975 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530976 }
977 else
978 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530979 BMCWEB_LOG_DEBUG << "Unsupported value for "
980 "BootSourceOverrideEnabled: "
981 << *bootEnable;
982 messages::propertyValueNotInList(aResp->res, *bootEnable,
983 "BootSourceOverrideEnabled");
984 return;
985 }
986 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530987
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700988 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530989 {
990 // Source target specified
991 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
992 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700993 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
994 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530995 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700996 BMCWEB_LOG_DEBUG
997 << "Invalid property value for BootSourceOverrideTarget: "
998 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530999 messages::propertyValueNotInList(aResp->res, *bootSource,
1000 "BootSourceTargetOverride");
1001 return;
1002 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001003 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301004
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001005 // Act on validated parameters
1006 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1007 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1008 const char *bootObj =
1009 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1010 : "/xyz/openbmc_project/control/host0/boot";
1011
1012 crow::connections::systemBus->async_method_call(
1013 [aResp](const boost::system::error_code ec) {
1014 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301015 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001016 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1017 messages::internalError(aResp->res);
1018 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301019 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001020 BMCWEB_LOG_DEBUG << "Boot source update done.";
1021 },
1022 "xyz.openbmc_project.Settings", bootObj,
1023 "org.freedesktop.DBus.Properties", "Set",
1024 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1025 std::variant<std::string>(bootSourceStr));
1026
1027 crow::connections::systemBus->async_method_call(
1028 [aResp](const boost::system::error_code ec) {
1029 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001031 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1032 messages::internalError(aResp->res);
1033 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301034 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001035 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1036 },
1037 "xyz.openbmc_project.Settings", bootObj,
1038 "org.freedesktop.DBus.Properties", "Set",
1039 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1040 std::variant<std::string>(bootModeStr));
1041
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301042 crow::connections::systemBus->async_method_call(
1043 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1044 if (ec)
1045 {
1046 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1047 messages::internalError(aResp->res);
1048 return;
1049 }
1050 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1051 },
1052 "xyz.openbmc_project.Settings",
1053 "/xyz/openbmc_project/control/host0/boot/one_time",
1054 "org.freedesktop.DBus.Properties", "Set",
1055 "xyz.openbmc_project.Object.Enable", "Enabled",
1056 std::variant<bool>(oneTimeSetting));
1057}
1058
1059/**
1060 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1061 * set boot source/boot mode properties.
1062 *
1063 * @param[in] aResp Shared pointer for generating response message.
1064 * @param[in] bootSource The boot source from incoming RF request.
1065 * @param[in] bootEnable The boot override enable from incoming RF request.
1066 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001067 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301068 */
1069static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1070 std::optional<std::string> bootSource,
1071 std::optional<std::string> bootEnable)
1072{
1073 BMCWEB_LOG_DEBUG << "Set boot information.";
1074
1075 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001076 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301077 bootEnable{std::move(bootEnable)}](
1078 const boost::system::error_code ec,
1079 const sdbusplus::message::variant<bool> &oneTime) {
1080 if (ec)
1081 {
1082 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1083 messages::internalError(aResp->res);
1084 return;
1085 }
1086
1087 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1088
1089 if (!oneTimePtr)
1090 {
1091 messages::internalError(aResp->res);
1092 return;
1093 }
1094
1095 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1096
1097 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1098 std::move(bootEnable));
1099 },
1100 "xyz.openbmc_project.Settings",
1101 "/xyz/openbmc_project/control/host0/boot/one_time",
1102 "org.freedesktop.DBus.Properties", "Get",
1103 "xyz.openbmc_project.Object.Enable", "Enabled");
1104}
1105
AppaRao Pulia6349912019-10-18 17:16:08 +05301106#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1107/**
1108 * @brief Retrieves provisioning status
1109 *
1110 * @param[in] aResp Shared pointer for completing asynchronous calls.
1111 *
1112 * @return None.
1113 */
1114void getProvisioningStatus(std::shared_ptr<AsyncResp> aResp)
1115{
1116 BMCWEB_LOG_DEBUG << "Get OEM information.";
1117 crow::connections::systemBus->async_method_call(
1118 [aResp](const boost::system::error_code ec,
1119 const std::vector<std::pair<std::string, VariantType>>
1120 &propertiesList) {
1121 if (ec)
1122 {
1123 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1124 messages::internalError(aResp->res);
1125 return;
1126 }
1127
1128 const bool *provState = nullptr;
1129 const bool *lockState = nullptr;
1130 for (const std::pair<std::string, VariantType> &property :
1131 propertiesList)
1132 {
1133 if (property.first == "UfmProvisioned")
1134 {
1135 provState = std::get_if<bool>(&property.second);
1136 }
1137 else if (property.first == "UfmLocked")
1138 {
1139 lockState = std::get_if<bool>(&property.second);
1140 }
1141 }
1142
1143 if ((provState == nullptr) || (lockState == nullptr))
1144 {
1145 BMCWEB_LOG_DEBUG << "Unable to get PFR attributes.";
1146 messages::internalError(aResp->res);
1147 return;
1148 }
1149
1150 nlohmann::json &oemPFR =
1151 aResp->res.jsonValue["Oem"]["OpenBmc"]["FirmwareProvisioning"];
1152 if (*provState == true)
1153 {
1154 if (*lockState == true)
1155 {
1156 oemPFR["ProvisioningStatus"] = "ProvisionedAndLocked";
1157 }
1158 else
1159 {
1160 oemPFR["ProvisioningStatus"] = "ProvisionedButNotLocked";
1161 }
1162 }
1163 else
1164 {
1165 oemPFR["ProvisioningStatus"] = "NotProvisioned";
1166 }
1167 },
1168 "xyz.openbmc_project.PFR.Manager", "/xyz/openbmc_project/pfr",
1169 "org.freedesktop.DBus.Properties", "GetAll",
1170 "xyz.openbmc_project.PFR.Attributes");
1171}
1172#endif
1173
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301174/**
Yong Li51709ff2019-09-30 14:13:04 +08001175 * @brief Translates watchdog timeout action DBUS property value to redfish.
1176 *
1177 * @param[in] dbusAction The watchdog timeout action in D-BUS.
1178 *
1179 * @return Returns as a string, the timeout action in Redfish terms. If
1180 * translation cannot be done, returns an empty string.
1181 */
1182static std::string dbusToRfWatchdogAction(const std::string &dbusAction)
1183{
1184 if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.None")
1185 {
1186 return "None";
1187 }
1188 else if (dbusAction ==
1189 "xyz.openbmc_project.State.Watchdog.Action.HardReset")
1190 {
1191 return "ResetSystem";
1192 }
1193 else if (dbusAction == "xyz.openbmc_project.State.Watchdog.Action.PowerOff")
1194 {
1195 return "PowerDown";
1196 }
1197 else if (dbusAction ==
1198 "xyz.openbmc_project.State.Watchdog.Action.PowerCycle")
1199 {
1200 return "PowerCycle";
1201 }
1202
1203 return "";
1204}
1205
1206/**
Yong Lic45f0082019-10-10 14:19:01 +08001207 *@brief Translates timeout action from Redfish to DBUS property value.
1208 *
1209 *@param[in] rfAction The timeout action in Redfish.
1210 *
1211 *@return Returns as a string, the time_out action as expected by DBUS.
1212 *If translation cannot be done, returns an empty string.
1213 */
1214
1215static std::string rfToDbusWDTTimeOutAct(const std::string &rfAction)
1216{
1217 if (rfAction == "None")
1218 {
1219 return "xyz.openbmc_project.State.Watchdog.Action.None";
1220 }
1221 else if (rfAction == "PowerCycle")
1222 {
1223 return "xyz.openbmc_project.State.Watchdog.Action.PowerCycle";
1224 }
1225 else if (rfAction == "PowerDown")
1226 {
1227 return "xyz.openbmc_project.State.Watchdog.Action.PowerOff";
1228 }
1229 else if (rfAction == "ResetSystem")
1230 {
1231 return "xyz.openbmc_project.State.Watchdog.Action.HardReset";
1232 }
1233
1234 return "";
1235}
1236
1237/**
Yong Li51709ff2019-09-30 14:13:04 +08001238 * @brief Retrieves host watchdog timer properties over DBUS
1239 *
1240 * @param[in] aResp Shared pointer for completing asynchronous calls.
1241 *
1242 * @return None.
1243 */
1244void getHostWatchdogTimer(std::shared_ptr<AsyncResp> aResp)
1245{
1246 BMCWEB_LOG_DEBUG << "Get host watchodg";
1247 crow::connections::systemBus->async_method_call(
1248 [aResp](const boost::system::error_code ec,
1249 PropertiesType &properties) {
1250 if (ec)
1251 {
1252 // watchdog service is stopped
1253 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1254 return;
1255 }
1256
1257 BMCWEB_LOG_DEBUG << "Got " << properties.size() << " wdt prop.";
1258
1259 nlohmann::json &hostWatchdogTimer =
1260 aResp->res.jsonValue["HostWatchdogTimer"];
1261
1262 // watchdog service is running/enabled
1263 hostWatchdogTimer["Status"]["State"] = "Enabled";
1264
1265 for (const auto &property : properties)
1266 {
1267 BMCWEB_LOG_DEBUG << "prop=" << property.first;
1268 if (property.first == "Enabled")
1269 {
1270 const bool *state = std::get_if<bool>(&property.second);
1271
1272 if (!state)
1273 {
1274 messages::internalError(aResp->res);
1275 continue;
1276 }
1277
1278 hostWatchdogTimer["FunctionEnabled"] = *state;
1279 }
1280 else if (property.first == "ExpireAction")
1281 {
1282 const std::string *s =
1283 std::get_if<std::string>(&property.second);
1284 if (!s)
1285 {
1286 messages::internalError(aResp->res);
1287 continue;
1288 }
1289
1290 std::string action = dbusToRfWatchdogAction(*s);
1291 if (action.empty())
1292 {
1293 messages::internalError(aResp->res);
1294 continue;
1295 }
1296 hostWatchdogTimer["TimeoutAction"] = action;
1297 }
1298 }
1299 },
1300 "xyz.openbmc_project.Watchdog", "/xyz/openbmc_project/watchdog/host0",
1301 "org.freedesktop.DBus.Properties", "GetAll",
1302 "xyz.openbmc_project.State.Watchdog");
1303}
1304
1305/**
Yong Lic45f0082019-10-10 14:19:01 +08001306 * @brief Sets Host WatchDog Timer properties.
1307 *
1308 * @param[in] aResp Shared pointer for generating response message.
1309 * @param[in] wdtEnable The WDTimer Enable value (true/false) from incoming
1310 * RF request.
1311 * @param[in] wdtTimeOutAction The WDT Timeout action, from incoming RF request.
1312 *
1313 * @return None.
1314 */
1315static void setWDTProperties(std::shared_ptr<AsyncResp> aResp,
1316 const std::optional<bool> wdtEnable,
1317 const std::optional<std::string> &wdtTimeOutAction)
1318{
1319 BMCWEB_LOG_DEBUG << "Set host watchdog";
1320
1321 if (wdtTimeOutAction)
1322 {
1323 std::string wdtTimeOutActStr = rfToDbusWDTTimeOutAct(*wdtTimeOutAction);
1324 // check if TimeOut Action is Valid
1325 if (wdtTimeOutActStr.empty())
1326 {
1327 BMCWEB_LOG_DEBUG << "Unsupported value for TimeoutAction: "
1328 << *wdtTimeOutAction;
1329 messages::propertyValueNotInList(aResp->res, *wdtTimeOutAction,
1330 "TimeoutAction");
1331 return;
1332 }
1333
1334 crow::connections::systemBus->async_method_call(
1335 [aResp](const boost::system::error_code ec) {
1336 if (ec)
1337 {
1338 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1339 messages::internalError(aResp->res);
1340 return;
1341 }
1342 },
1343 "xyz.openbmc_project.Watchdog",
1344 "/xyz/openbmc_project/watchdog/host0",
1345 "org.freedesktop.DBus.Properties", "Set",
1346 "xyz.openbmc_project.State.Watchdog", "ExpireAction",
1347 std::variant<std::string>(wdtTimeOutActStr));
1348 }
1349
1350 if (wdtEnable)
1351 {
1352 crow::connections::systemBus->async_method_call(
1353 [aResp](const boost::system::error_code ec) {
1354 if (ec)
1355 {
1356 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1357 messages::internalError(aResp->res);
1358 return;
1359 }
1360 },
1361 "xyz.openbmc_project.Watchdog",
1362 "/xyz/openbmc_project/watchdog/host0",
1363 "org.freedesktop.DBus.Properties", "Set",
1364 "xyz.openbmc_project.State.Watchdog", "Enabled",
1365 std::variant<bool>(*wdtEnable));
1366 }
1367}
1368
1369/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001370 * SystemsCollection derived class for delivering ComputerSystems Collection
1371 * Schema
1372 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001373class SystemsCollection : public Node
1374{
1375 public:
1376 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1377 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001378 entityPrivileges = {
1379 {boost::beast::http::verb::get, {{"Login"}}},
1380 {boost::beast::http::verb::head, {{"Login"}}},
1381 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1382 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1383 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1384 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1385 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001386
Ed Tanous1abe55e2018-09-05 08:30:59 -07001387 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001388 void doGet(crow::Response &res, const crow::Request &req,
1389 const std::vector<std::string> &params) override
1390 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001391 res.jsonValue["@odata.type"] =
1392 "#ComputerSystemCollection.ComputerSystemCollection";
1393 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1394 res.jsonValue["@odata.context"] =
1395 "/redfish/v1/"
1396 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1397 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001398 res.jsonValue["Members"] = {
1399 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1400 res.jsonValue["Members@odata.count"] = 1;
1401 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001402 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001403};
1404
1405/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001406 * SystemActionsReset class supports handle POST method for Reset action.
1407 * The class retrieves and sends data directly to D-Bus.
1408 */
1409class SystemActionsReset : public Node
1410{
1411 public:
1412 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001413 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001414 {
1415 entityPrivileges = {
1416 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1417 }
1418
1419 private:
1420 /**
1421 * Function handles POST method request.
1422 * Analyzes POST body message before sends Reset request data to D-Bus.
1423 */
1424 void doPost(crow::Response &res, const crow::Request &req,
1425 const std::vector<std::string> &params) override
1426 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001427 auto asyncResp = std::make_shared<AsyncResp>(res);
1428
1429 std::string resetType;
1430 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001431 {
1432 return;
1433 }
1434
Jason M. Billsd22c8392019-06-03 13:59:03 -07001435 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001436 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001437 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001438 if (resetType == "On")
1439 {
1440 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001441 hostCommand = true;
1442 }
1443 else if (resetType == "ForceOff")
1444 {
1445 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1446 hostCommand = false;
1447 }
1448 else if (resetType == "ForceOn")
1449 {
1450 command = "xyz.openbmc_project.State.Host.Transition.On";
1451 hostCommand = true;
1452 }
1453 else if (resetType == "ForceRestart")
1454 {
1455 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1456 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001457 }
1458 else if (resetType == "GracefulShutdown")
1459 {
1460 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001461 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001462 }
1463 else if (resetType == "GracefulRestart")
1464 {
1465 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001466 hostCommand = true;
1467 }
1468 else if (resetType == "PowerCycle")
1469 {
1470 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1471 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001472 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001473 else if (resetType == "Nmi")
1474 {
1475 doNMI(asyncResp);
1476 return;
1477 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001478 else
1479 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001480 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001481 return;
1482 }
1483
Jason M. Billsd22c8392019-06-03 13:59:03 -07001484 if (hostCommand)
1485 {
1486 crow::connections::systemBus->async_method_call(
1487 [asyncResp, resetType](const boost::system::error_code ec) {
1488 if (ec)
1489 {
1490 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1491 if (ec.value() == boost::asio::error::invalid_argument)
1492 {
1493 messages::actionParameterNotSupported(
1494 asyncResp->res, resetType, "Reset");
1495 }
1496 else
1497 {
1498 messages::internalError(asyncResp->res);
1499 }
1500 return;
1501 }
1502 messages::success(asyncResp->res);
1503 },
1504 "xyz.openbmc_project.State.Host",
1505 "/xyz/openbmc_project/state/host0",
1506 "org.freedesktop.DBus.Properties", "Set",
1507 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1508 std::variant<std::string>{command});
1509 }
1510 else
1511 {
1512 crow::connections::systemBus->async_method_call(
1513 [asyncResp, resetType](const boost::system::error_code ec) {
1514 if (ec)
1515 {
1516 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1517 if (ec.value() == boost::asio::error::invalid_argument)
1518 {
1519 messages::actionParameterNotSupported(
1520 asyncResp->res, resetType, "Reset");
1521 }
1522 else
1523 {
1524 messages::internalError(asyncResp->res);
1525 }
1526 return;
1527 }
1528 messages::success(asyncResp->res);
1529 },
1530 "xyz.openbmc_project.State.Chassis",
1531 "/xyz/openbmc_project/state/chassis0",
1532 "org.freedesktop.DBus.Properties", "Set",
1533 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1534 std::variant<std::string>{command});
1535 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001536 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001537 /**
1538 * Function transceives data with dbus directly.
1539 */
1540 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1541 {
1542 constexpr char const *serviceName =
1543 "xyz.openbmc_project.Control.Host.NMI";
1544 constexpr char const *objectPath =
1545 "/xyz/openbmc_project/control/host0/nmi";
1546 constexpr char const *interfaceName =
1547 "xyz.openbmc_project.Control.Host.NMI";
1548 constexpr char const *method = "NMI";
1549
1550 crow::connections::systemBus->async_method_call(
1551 [asyncResp](const boost::system::error_code ec) {
1552 if (ec)
1553 {
1554 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1555 messages::internalError(asyncResp->res);
1556 return;
1557 }
1558 messages::success(asyncResp->res);
1559 },
1560 serviceName, objectPath, interfaceName, method);
1561 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001562};
1563
1564/**
Ed Tanous66173382018-08-15 18:20:59 -07001565 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001566 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001567class Systems : public Node
1568{
1569 public:
1570 /*
1571 * Default Constructor
1572 */
Ed Tanous029573d2019-02-01 10:57:49 -08001573 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001574 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001575 entityPrivileges = {
1576 {boost::beast::http::verb::get, {{"Login"}}},
1577 {boost::beast::http::verb::head, {{"Login"}}},
1578 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1579 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1580 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1581 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001582 }
1583
Ed Tanous1abe55e2018-09-05 08:30:59 -07001584 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001585 /**
1586 * Functions triggers appropriate requests on DBus
1587 */
1588 void doGet(crow::Response &res, const crow::Request &req,
1589 const std::vector<std::string> &params) override
1590 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301591 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001592 res.jsonValue["@odata.context"] =
1593 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001594 res.jsonValue["Name"] = "Computer System";
1595 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001596 res.jsonValue["SystemType"] = "Physical";
1597 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001598 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1599 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
1600 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
1601 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001602 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001603
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001604 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001605 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001606 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001607 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001608 res.jsonValue["Storage"] = {
1609 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001610
Ed Tanouscc340dd2018-08-29 13:43:38 -07001611 // TODO Need to support ForceRestart.
1612 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1613 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001614 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001615 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001616 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001617 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001618
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001619 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001620 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001621
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001622 res.jsonValue["Links"]["ManagedBy"] = {
1623 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1624
1625 res.jsonValue["Status"] = {
1626 {"Health", "OK"},
1627 {"State", "Enabled"},
1628 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001629 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001630
James Feist2ad9c2f2019-10-29 16:26:48 -07001631 constexpr const std::array<const char *, 3> inventoryForSystems = {
James Feistb49ac872019-05-21 15:12:01 -07001632 "xyz.openbmc_project.Inventory.Item.Dimm",
James Feist2ad9c2f2019-10-29 16:26:48 -07001633 "xyz.openbmc_project.Inventory.Item.Cpu",
1634 "xyz.openbmc_project.Inventory.Item.Drive"};
James Feistb49ac872019-05-21 15:12:01 -07001635
1636 auto health = std::make_shared<HealthPopulate>(asyncResp);
1637 crow::connections::systemBus->async_method_call(
1638 [health](const boost::system::error_code ec,
1639 std::vector<std::string> &resp) {
1640 if (ec)
1641 {
1642 // no inventory
1643 return;
1644 }
1645
1646 health->inventory = std::move(resp);
1647 },
1648 "xyz.openbmc_project.ObjectMapper",
1649 "/xyz/openbmc_project/object_mapper",
1650 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1651 int32_t(0), inventoryForSystems);
1652
1653 health->populate();
1654
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001655 getMainChassisId(asyncResp, [](const std::string &chassisId,
1656 std::shared_ptr<AsyncResp> aRsp) {
1657 aRsp->res.jsonValue["Links"]["Chassis"] = {
1658 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1659 });
Ed Tanous6c34de42018-08-29 13:37:36 -07001660 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -07001661 asyncResp,
Carol Wangfc41ff62019-10-23 15:14:54 +08001662 [](bool asserted, const std::shared_ptr<AsyncResp> aRsp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001663 if (asserted)
1664 {
Carol Wangfc41ff62019-10-23 15:14:54 +08001665 aRsp->res.jsonValue["IndicatorLED"] = "On";
Ed Tanous1abe55e2018-09-05 08:30:59 -07001666 }
1667 else
1668 {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001669 aRsp->res.jsonValue["IndicatorLED"] = "Off";
Ed Tanous1abe55e2018-09-05 08:30:59 -07001670 }
1671 });
James Feist5bc2dc82019-10-22 14:33:16 -07001672 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001673 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301674 getBootProperties(asyncResp);
Jason M. Billsadbe1922019-10-14 15:44:35 -07001675 getPCIeDeviceList(asyncResp, "PCIeDevices");
Yong Li51709ff2019-09-30 14:13:04 +08001676 getHostWatchdogTimer(asyncResp);
AppaRao Pulia6349912019-10-18 17:16:08 +05301677#ifdef BMCWEB_ENABLE_REDFISH_PROVISIONING_FEATURE
1678 getProvisioningStatus(asyncResp);
1679#endif
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001680 }
1681
Ed Tanous1abe55e2018-09-05 08:30:59 -07001682 void doPatch(crow::Response &res, const crow::Request &req,
1683 const std::vector<std::string> &params) override
1684 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301685 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301686 std::optional<nlohmann::json> bootProps;
Yong Lic45f0082019-10-10 14:19:01 +08001687 std::optional<nlohmann::json> wdtTimerProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001688 auto asyncResp = std::make_shared<AsyncResp>(res);
1689
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001690 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
Yong Lic45f0082019-10-10 14:19:01 +08001691 bootProps, "WatchdogTimer", wdtTimerProps))
Ed Tanous66173382018-08-15 18:20:59 -07001692 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001693 return;
1694 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301695
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001696 res.result(boost::beast::http::status::no_content);
Yong Lic45f0082019-10-10 14:19:01 +08001697
1698 if (wdtTimerProps)
1699 {
1700 std::optional<bool> wdtEnable;
1701 std::optional<std::string> wdtTimeOutAction;
1702
1703 if (!json_util::readJson(*wdtTimerProps, asyncResp->res,
1704 "FunctionEnabled", wdtEnable,
1705 "TimeoutAction", wdtTimeOutAction))
1706 {
1707 return;
1708 }
1709 setWDTProperties(asyncResp, std::move(wdtEnable),
1710 std::move(wdtTimeOutAction));
1711 }
1712
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301713 if (bootProps)
1714 {
1715 std::optional<std::string> bootSource;
1716 std::optional<std::string> bootEnable;
1717
1718 if (!json_util::readJson(*bootProps, asyncResp->res,
1719 "BootSourceOverrideTarget", bootSource,
1720 "BootSourceOverrideEnabled", bootEnable))
1721 {
1722 return;
1723 }
1724 setBootProperties(asyncResp, std::move(bootSource),
1725 std::move(bootEnable));
1726 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001727
Ed Tanous9712f8a2018-09-21 13:38:49 -07001728 if (indicatorLed)
1729 {
1730 std::string dbusLedState;
Jennifer Leed573bb22019-04-10 13:49:51 -07001731 if (*indicatorLed == "Lit")
Ed Tanous66173382018-08-15 18:20:59 -07001732 {
Jennifer Leed573bb22019-04-10 13:49:51 -07001733 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.On";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001734 }
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001735 else if (*indicatorLed == "Blinking")
Ed Tanous9712f8a2018-09-21 13:38:49 -07001736 {
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001737 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Blink";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001738 }
1739 else if (*indicatorLed == "Off")
1740 {
1741 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -07001742 }
1743 else
1744 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -08001745 messages::propertyValueNotInList(res, *indicatorLed,
1746 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -07001747 return;
1748 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001749
Ed Tanous9712f8a2018-09-21 13:38:49 -07001750 // Update led group
1751 BMCWEB_LOG_DEBUG << "Update led group.";
1752 crow::connections::systemBus->async_method_call(
Santosh Puranikcde19e52019-02-20 00:10:56 +05301753 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001754 if (ec)
1755 {
1756 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001757 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001758 return;
1759 }
1760 BMCWEB_LOG_DEBUG << "Led group update done.";
1761 },
1762 "xyz.openbmc_project.LED.GroupManager",
1763 "/xyz/openbmc_project/led/groups/enclosure_identify",
1764 "org.freedesktop.DBus.Properties", "Set",
1765 "xyz.openbmc_project.Led.Group", "Asserted",
Ed Tanousabf2add2019-01-22 16:40:12 -08001766 std::variant<bool>(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001767 (dbusLedState !=
1768 "xyz.openbmc_project.Led.Physical.Action.Off")));
1769
Ed Tanous9712f8a2018-09-21 13:38:49 -07001770 // Update identify led status
1771 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
1772 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001773 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001774 if (ec)
1775 {
1776 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001777 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001778 return;
1779 }
1780 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001781 },
1782 "xyz.openbmc_project.LED.Controller.identify",
1783 "/xyz/openbmc_project/led/physical/identify",
1784 "org.freedesktop.DBus.Properties", "Set",
1785 "xyz.openbmc_project.Led.Physical", "State",
Ed Tanousabf2add2019-01-22 16:40:12 -08001786 std::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001787 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001788 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001789};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001790} // namespace redfish