blob: b91296f18b1324ff609aa268be82491eda02c35a [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
615template <typename CallbackFunc>
616void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
617{
618 BMCWEB_LOG_DEBUG << "Get identify led properties";
619 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700620 [aResp,
621 callback{std::move(callback)}](const boost::system::error_code ec,
622 const PropertiesType &properties) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700623 if (ec)
624 {
625 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700626 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700627 return;
628 }
629 BMCWEB_LOG_DEBUG << "Got " << properties.size()
Gunnar Mills698654b2019-10-16 13:17:37 -0500630 << " led properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700631 std::string output;
632 for (const auto &property : properties)
633 {
634 if (property.first == "State")
635 {
636 const std::string *s =
Ed Tanousabf2add2019-01-22 16:40:12 -0800637 std::get_if<std::string>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700638 if (nullptr != s)
639 {
640 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
641 const auto pos = s->rfind('.');
642 if (pos != std::string::npos)
643 {
644 auto led = s->substr(pos + 1);
645 for (const std::pair<const char *, const char *>
646 &p :
647 std::array<
648 std::pair<const char *, const char *>, 3>{
649 {{"On", "Lit"},
650 {"Blink", "Blinking"},
651 {"Off", "Off"}}})
652 {
653 if (led == p.first)
654 {
655 output = p.second;
656 }
657 }
658 }
659 }
660 }
661 }
662 callback(output, aResp);
663 },
664 "xyz.openbmc_project.LED.Controller.identify",
665 "/xyz/openbmc_project/led/physical/identify",
666 "org.freedesktop.DBus.Properties", "GetAll",
667 "xyz.openbmc_project.Led.Physical");
668}
Ed Tanous6c34de42018-08-29 13:37:36 -0700669/**
670 * @brief Retrieves host state properties over dbus
671 *
672 * @param[in] aResp Shared pointer for completing asynchronous calls.
673 *
674 * @return None.
675 */
676void getHostState(std::shared_ptr<AsyncResp> aResp)
677{
678 BMCWEB_LOG_DEBUG << "Get host information.";
679 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800680 [aResp](const boost::system::error_code ec,
681 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700682 if (ec)
683 {
684 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700685 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700686 return;
687 }
Ed Tanous66173382018-08-15 18:20:59 -0700688
Ed Tanousabf2add2019-01-22 16:40:12 -0800689 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700690 BMCWEB_LOG_DEBUG << "Host state: " << *s;
691 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700692 {
Ed Tanous66173382018-08-15 18:20:59 -0700693 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800694 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700695 {
Ed Tanous66173382018-08-15 18:20:59 -0700696 aResp->res.jsonValue["PowerState"] = "On";
697 aResp->res.jsonValue["Status"]["State"] = "Enabled";
698 }
699 else
700 {
701 aResp->res.jsonValue["PowerState"] = "Off";
702 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700703 }
704 }
705 },
706 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700707 "org.freedesktop.DBus.Properties", "Get",
708 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700709}
710
711/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530712 * @brief Traslates boot source DBUS property value to redfish.
713 *
714 * @param[in] dbusSource The boot source in DBUS speak.
715 *
716 * @return Returns as a string, the boot source in Redfish terms. If translation
717 * cannot be done, returns an empty string.
718 */
719static std::string dbusToRfBootSource(const std::string &dbusSource)
720{
721 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
722 {
723 return "None";
724 }
725 else if (dbusSource ==
726 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
727 {
728 return "Hdd";
729 }
730 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530731 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530732 {
733 return "Cd";
734 }
735 else if (dbusSource ==
736 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
737 {
738 return "Pxe";
739 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700740 else if (dbusSource ==
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700741 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia")
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700742 {
743 return "Usb";
744 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530745 else
746 {
747 return "";
748 }
749}
750
751/**
752 * @brief Traslates boot mode DBUS property value to redfish.
753 *
754 * @param[in] dbusMode The boot mode in DBUS speak.
755 *
756 * @return Returns as a string, the boot mode in Redfish terms. If translation
757 * cannot be done, returns an empty string.
758 */
759static std::string dbusToRfBootMode(const std::string &dbusMode)
760{
761 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
762 {
763 return "None";
764 }
765 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
766 {
767 return "Diags";
768 }
769 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
770 {
771 return "BiosSetup";
772 }
773 else
774 {
775 return "";
776 }
777}
778
779/**
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700780 * @brief Traslates boot source from Redfish to the DBus boot paths.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530781 *
782 * @param[in] rfSource The boot source in Redfish.
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700783 * @param[out] bootSource The DBus source
784 * @param[out] bootMode the DBus boot mode
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530785 *
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700786 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530787 */
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700788static int assignBootParameters(std::shared_ptr<AsyncResp> aResp,
789 const std::string &rfSource,
790 std::string &bootSource, std::string &bootMode)
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530791{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700792 // The caller has initialized the bootSource and bootMode to:
793 // bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
794 // bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
795 // Only modify the bootSource/bootMode variable needed to achieve the
796 // desired boot action.
797
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530798 if (rfSource == "None")
799 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700800 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530801 }
802 else if (rfSource == "Pxe")
803 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700804 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
805 }
806 else if (rfSource == "Hdd")
807 {
808 bootSource = "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
809 }
810 else if (rfSource == "Diags")
811 {
812 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
813 }
814 else if (rfSource == "Cd")
815 {
816 bootSource =
817 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
818 }
819 else if (rfSource == "BiosSetup")
820 {
821 bootMode = "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530822 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700823 else if (rfSource == "Usb")
824 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700825 bootSource =
826 "xyz.openbmc_project.Control.Boot.Source.Sources.RemovableMedia";
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700827 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530828 else
829 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700830 BMCWEB_LOG_DEBUG << "Invalid property value for "
831 "BootSourceOverrideTarget: "
832 << bootSource;
833 messages::propertyValueNotInList(aResp->res, rfSource,
834 "BootSourceTargetOverride");
835 return -1;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530836 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700837 return 0;
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530838}
839
840/**
841 * @brief Retrieves boot mode over DBUS and fills out the response
842 *
843 * @param[in] aResp Shared pointer for generating response message.
844 * @param[in] bootDbusObj The dbus object to query for boot properties.
845 *
846 * @return None.
847 */
848static void getBootMode(std::shared_ptr<AsyncResp> aResp,
849 std::string bootDbusObj)
850{
851 crow::connections::systemBus->async_method_call(
852 [aResp](const boost::system::error_code ec,
853 const std::variant<std::string> &bootMode) {
854 if (ec)
855 {
856 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
857 messages::internalError(aResp->res);
858 return;
859 }
860
861 const std::string *bootModeStr =
862 std::get_if<std::string>(&bootMode);
863
864 if (!bootModeStr)
865 {
866 messages::internalError(aResp->res);
867 return;
868 }
869
870 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
871
872 // TODO (Santosh): Do we need to support override mode?
873 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
874 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
875 "AllowableValues"] = {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -0700876 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup", "Usb"};
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530877
878 if (*bootModeStr !=
879 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
880 {
881 auto rfMode = dbusToRfBootMode(*bootModeStr);
882 if (!rfMode.empty())
883 {
884 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
885 rfMode;
886 }
887 }
888
889 // If the BootSourceOverrideTarget is still "None" at the end,
890 // reset the BootSourceOverrideEnabled to indicate that
891 // overrides are disabled
892 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
893 "None")
894 {
895 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
896 "Disabled";
897 }
898 },
899 "xyz.openbmc_project.Settings", bootDbusObj,
900 "org.freedesktop.DBus.Properties", "Get",
901 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
902}
903
904/**
905 * @brief Retrieves boot source over DBUS
906 *
907 * @param[in] aResp Shared pointer for generating response message.
908 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
909 *
910 * @return None.
911 */
912static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
913{
914 std::string bootDbusObj =
915 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
916 : "/xyz/openbmc_project/control/host0/boot";
917
918 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
919 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
920 (oneTimeEnabled) ? "Once" : "Continuous";
921
922 crow::connections::systemBus->async_method_call(
923 [aResp, bootDbusObj](const boost::system::error_code ec,
924 const std::variant<std::string> &bootSource) {
925 if (ec)
926 {
927 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
928 messages::internalError(aResp->res);
929 return;
930 }
931
932 const std::string *bootSourceStr =
933 std::get_if<std::string>(&bootSource);
934
935 if (!bootSourceStr)
936 {
937 messages::internalError(aResp->res);
938 return;
939 }
940 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
941
942 auto rfSource = dbusToRfBootSource(*bootSourceStr);
943 if (!rfSource.empty())
944 {
945 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
946 rfSource;
947 }
948 },
949 "xyz.openbmc_project.Settings", bootDbusObj,
950 "org.freedesktop.DBus.Properties", "Get",
951 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
952 getBootMode(std::move(aResp), std::move(bootDbusObj));
953}
954
955/**
956 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
957 * get boot source and boot mode.
958 *
959 * @param[in] aResp Shared pointer for generating response message.
960 *
961 * @return None.
962 */
963static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
964{
965 BMCWEB_LOG_DEBUG << "Get boot information.";
966
967 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800968 [aResp](const boost::system::error_code ec,
969 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530970 if (ec)
971 {
972 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
James Feist2a833c72019-07-19 10:17:13 -0700973 // not an error, don't have to have the interface
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530974 return;
975 }
976
977 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
978
979 if (!oneTimePtr)
980 {
981 messages::internalError(aResp->res);
982 return;
983 }
984 getBootSource(aResp, *oneTimePtr);
985 },
986 "xyz.openbmc_project.Settings",
987 "/xyz/openbmc_project/control/host0/boot/one_time",
988 "org.freedesktop.DBus.Properties", "Get",
989 "xyz.openbmc_project.Object.Enable", "Enabled");
990}
991
992/**
993 * @brief Sets boot properties into DBUS object(s).
994 *
995 * @param[in] aResp Shared pointer for generating response message.
996 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
997 * @param[in] bootSource The boot source to set.
998 * @param[in] bootEnable The source override "enable" to set.
999 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001000 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301001 */
1002static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
1003 bool oneTimeEnabled,
1004 std::optional<std::string> bootSource,
1005 std::optional<std::string> bootEnable)
1006{
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001007 std::string bootSourceStr =
1008 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
1009 std::string bootModeStr =
1010 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301011 bool oneTimeSetting = oneTimeEnabled;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001012 bool useBootSource = true;
1013
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301014 // Validate incoming parameters
1015 if (bootEnable)
1016 {
1017 if (*bootEnable == "Once")
1018 {
1019 oneTimeSetting = true;
1020 }
1021 else if (*bootEnable == "Continuous")
1022 {
1023 oneTimeSetting = false;
1024 }
1025 else if (*bootEnable == "Disabled")
1026 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001027 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301028 oneTimeSetting = false;
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001029 useBootSource = false;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301030 }
1031 else
1032 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301033 BMCWEB_LOG_DEBUG << "Unsupported value for "
1034 "BootSourceOverrideEnabled: "
1035 << *bootEnable;
1036 messages::propertyValueNotInList(aResp->res, *bootEnable,
1037 "BootSourceOverrideEnabled");
1038 return;
1039 }
1040 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301041
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001042 if (bootSource && useBootSource)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301043 {
1044 // Source target specified
1045 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
1046 // Figure out which DBUS interface and property to use
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001047 if (assignBootParameters(aResp, *bootSource, bootSourceStr,
1048 bootModeStr))
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301049 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001050 BMCWEB_LOG_DEBUG
1051 << "Invalid property value for BootSourceOverrideTarget: "
1052 << *bootSource;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301053 messages::propertyValueNotInList(aResp->res, *bootSource,
1054 "BootSourceTargetOverride");
1055 return;
1056 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001057 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301058
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001059 // Act on validated parameters
1060 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
1061 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
1062 const char *bootObj =
1063 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
1064 : "/xyz/openbmc_project/control/host0/boot";
1065
1066 crow::connections::systemBus->async_method_call(
1067 [aResp](const boost::system::error_code ec) {
1068 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301069 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001070 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1071 messages::internalError(aResp->res);
1072 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301073 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001074 BMCWEB_LOG_DEBUG << "Boot source update done.";
1075 },
1076 "xyz.openbmc_project.Settings", bootObj,
1077 "org.freedesktop.DBus.Properties", "Set",
1078 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
1079 std::variant<std::string>(bootSourceStr));
1080
1081 crow::connections::systemBus->async_method_call(
1082 [aResp](const boost::system::error_code ec) {
1083 if (ec)
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301084 {
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001085 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1086 messages::internalError(aResp->res);
1087 return;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301088 }
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001089 BMCWEB_LOG_DEBUG << "Boot mode update done.";
1090 },
1091 "xyz.openbmc_project.Settings", bootObj,
1092 "org.freedesktop.DBus.Properties", "Set",
1093 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
1094 std::variant<std::string>(bootModeStr));
1095
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301096 crow::connections::systemBus->async_method_call(
1097 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
1098 if (ec)
1099 {
1100 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1101 messages::internalError(aResp->res);
1102 return;
1103 }
1104 BMCWEB_LOG_DEBUG << "Boot enable update done.";
1105 },
1106 "xyz.openbmc_project.Settings",
1107 "/xyz/openbmc_project/control/host0/boot/one_time",
1108 "org.freedesktop.DBus.Properties", "Set",
1109 "xyz.openbmc_project.Object.Enable", "Enabled",
1110 std::variant<bool>(oneTimeSetting));
1111}
1112
1113/**
1114 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
1115 * set boot source/boot mode properties.
1116 *
1117 * @param[in] aResp Shared pointer for generating response message.
1118 * @param[in] bootSource The boot source from incoming RF request.
1119 * @param[in] bootEnable The boot override enable from incoming RF request.
1120 *
Johnathan Mantey265c1602019-08-08 11:02:51 -07001121 * @return Integer error code.
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301122 */
1123static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
1124 std::optional<std::string> bootSource,
1125 std::optional<std::string> bootEnable)
1126{
1127 BMCWEB_LOG_DEBUG << "Set boot information.";
1128
1129 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001130 [aResp, bootSource{std::move(bootSource)},
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301131 bootEnable{std::move(bootEnable)}](
1132 const boost::system::error_code ec,
1133 const sdbusplus::message::variant<bool> &oneTime) {
1134 if (ec)
1135 {
1136 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
1137 messages::internalError(aResp->res);
1138 return;
1139 }
1140
1141 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
1142
1143 if (!oneTimePtr)
1144 {
1145 messages::internalError(aResp->res);
1146 return;
1147 }
1148
1149 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
1150
1151 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
1152 std::move(bootEnable));
1153 },
1154 "xyz.openbmc_project.Settings",
1155 "/xyz/openbmc_project/control/host0/boot/one_time",
1156 "org.freedesktop.DBus.Properties", "Get",
1157 "xyz.openbmc_project.Object.Enable", "Enabled");
1158}
1159
1160/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001161 * SystemsCollection derived class for delivering ComputerSystems Collection
1162 * Schema
1163 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001164class SystemsCollection : public Node
1165{
1166 public:
1167 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
1168 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001169 entityPrivileges = {
1170 {boost::beast::http::verb::get, {{"Login"}}},
1171 {boost::beast::http::verb::head, {{"Login"}}},
1172 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1173 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1174 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1175 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1176 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001177
Ed Tanous1abe55e2018-09-05 08:30:59 -07001178 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001179 void doGet(crow::Response &res, const crow::Request &req,
1180 const std::vector<std::string> &params) override
1181 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001182 res.jsonValue["@odata.type"] =
1183 "#ComputerSystemCollection.ComputerSystemCollection";
1184 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1185 res.jsonValue["@odata.context"] =
1186 "/redfish/v1/"
1187 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1188 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001189 res.jsonValue["Members"] = {
1190 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1191 res.jsonValue["Members@odata.count"] = 1;
1192 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001193 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001194};
1195
1196/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001197 * SystemActionsReset class supports handle POST method for Reset action.
1198 * The class retrieves and sends data directly to D-Bus.
1199 */
1200class SystemActionsReset : public Node
1201{
1202 public:
1203 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001204 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001205 {
1206 entityPrivileges = {
1207 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1208 }
1209
1210 private:
1211 /**
1212 * Function handles POST method request.
1213 * Analyzes POST body message before sends Reset request data to D-Bus.
1214 */
1215 void doPost(crow::Response &res, const crow::Request &req,
1216 const std::vector<std::string> &params) override
1217 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001218 auto asyncResp = std::make_shared<AsyncResp>(res);
1219
1220 std::string resetType;
1221 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001222 {
1223 return;
1224 }
1225
Jason M. Billsd22c8392019-06-03 13:59:03 -07001226 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001227 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001228 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001229 if (resetType == "On")
1230 {
1231 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001232 hostCommand = true;
1233 }
1234 else if (resetType == "ForceOff")
1235 {
1236 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1237 hostCommand = false;
1238 }
1239 else if (resetType == "ForceOn")
1240 {
1241 command = "xyz.openbmc_project.State.Host.Transition.On";
1242 hostCommand = true;
1243 }
1244 else if (resetType == "ForceRestart")
1245 {
1246 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1247 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001248 }
1249 else if (resetType == "GracefulShutdown")
1250 {
1251 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001252 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001253 }
1254 else if (resetType == "GracefulRestart")
1255 {
1256 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001257 hostCommand = true;
1258 }
1259 else if (resetType == "PowerCycle")
1260 {
1261 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1262 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001263 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001264 else if (resetType == "Nmi")
1265 {
1266 doNMI(asyncResp);
1267 return;
1268 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001269 else
1270 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001271 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001272 return;
1273 }
1274
Jason M. Billsd22c8392019-06-03 13:59:03 -07001275 if (hostCommand)
1276 {
1277 crow::connections::systemBus->async_method_call(
1278 [asyncResp, resetType](const boost::system::error_code ec) {
1279 if (ec)
1280 {
1281 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1282 if (ec.value() == boost::asio::error::invalid_argument)
1283 {
1284 messages::actionParameterNotSupported(
1285 asyncResp->res, resetType, "Reset");
1286 }
1287 else
1288 {
1289 messages::internalError(asyncResp->res);
1290 }
1291 return;
1292 }
1293 messages::success(asyncResp->res);
1294 },
1295 "xyz.openbmc_project.State.Host",
1296 "/xyz/openbmc_project/state/host0",
1297 "org.freedesktop.DBus.Properties", "Set",
1298 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1299 std::variant<std::string>{command});
1300 }
1301 else
1302 {
1303 crow::connections::systemBus->async_method_call(
1304 [asyncResp, resetType](const boost::system::error_code ec) {
1305 if (ec)
1306 {
1307 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1308 if (ec.value() == boost::asio::error::invalid_argument)
1309 {
1310 messages::actionParameterNotSupported(
1311 asyncResp->res, resetType, "Reset");
1312 }
1313 else
1314 {
1315 messages::internalError(asyncResp->res);
1316 }
1317 return;
1318 }
1319 messages::success(asyncResp->res);
1320 },
1321 "xyz.openbmc_project.State.Chassis",
1322 "/xyz/openbmc_project/state/chassis0",
1323 "org.freedesktop.DBus.Properties", "Set",
1324 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1325 std::variant<std::string>{command});
1326 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001327 }
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001328 /**
1329 * Function transceives data with dbus directly.
1330 */
1331 void doNMI(const std::shared_ptr<AsyncResp> &asyncResp)
1332 {
1333 constexpr char const *serviceName =
1334 "xyz.openbmc_project.Control.Host.NMI";
1335 constexpr char const *objectPath =
1336 "/xyz/openbmc_project/control/host0/nmi";
1337 constexpr char const *interfaceName =
1338 "xyz.openbmc_project.Control.Host.NMI";
1339 constexpr char const *method = "NMI";
1340
1341 crow::connections::systemBus->async_method_call(
1342 [asyncResp](const boost::system::error_code ec) {
1343 if (ec)
1344 {
1345 BMCWEB_LOG_ERROR << " Bad D-Bus request error: " << ec;
1346 messages::internalError(asyncResp->res);
1347 return;
1348 }
1349 messages::success(asyncResp->res);
1350 },
1351 serviceName, objectPath, interfaceName, method);
1352 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001353};
1354
1355/**
Ed Tanous66173382018-08-15 18:20:59 -07001356 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001357 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001358class Systems : public Node
1359{
1360 public:
1361 /*
1362 * Default Constructor
1363 */
Ed Tanous029573d2019-02-01 10:57:49 -08001364 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001365 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001366 entityPrivileges = {
1367 {boost::beast::http::verb::get, {{"Login"}}},
1368 {boost::beast::http::verb::head, {{"Login"}}},
1369 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1370 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1371 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1372 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001373 }
1374
Ed Tanous1abe55e2018-09-05 08:30:59 -07001375 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001376 /**
1377 * Functions triggers appropriate requests on DBus
1378 */
1379 void doGet(crow::Response &res, const crow::Request &req,
1380 const std::vector<std::string> &params) override
1381 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301382 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001383 res.jsonValue["@odata.context"] =
1384 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001385 res.jsonValue["Name"] = "Computer System";
1386 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001387 res.jsonValue["SystemType"] = "Physical";
1388 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001389 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1390 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
1391 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
1392 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001393 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001394
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001395 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001396 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001397 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001398 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001399 res.jsonValue["Storage"] = {
1400 {"@odata.id", "/redfish/v1/Systems/system/Storage"}};
Ed Tanous029573d2019-02-01 10:57:49 -08001401
Ed Tanouscc340dd2018-08-29 13:43:38 -07001402 // TODO Need to support ForceRestart.
1403 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1404 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001405 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001406 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001407 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
Lakshminarayana R. Kammathbfd5b822019-06-17 12:11:01 -05001408 "GracefulShutdown", "PowerCycle", "Nmi"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001409
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001410 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001411 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001412
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001413 res.jsonValue["Links"]["ManagedBy"] = {
1414 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1415
1416 res.jsonValue["Status"] = {
1417 {"Health", "OK"},
1418 {"State", "Enabled"},
1419 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001420 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001421
James Feistb49ac872019-05-21 15:12:01 -07001422 constexpr const std::array<const char *, 2> inventoryForSystems = {
1423 "xyz.openbmc_project.Inventory.Item.Dimm",
1424 "xyz.openbmc_project.Inventory.Item.Cpu"};
1425
1426 auto health = std::make_shared<HealthPopulate>(asyncResp);
1427 crow::connections::systemBus->async_method_call(
1428 [health](const boost::system::error_code ec,
1429 std::vector<std::string> &resp) {
1430 if (ec)
1431 {
1432 // no inventory
1433 return;
1434 }
1435
1436 health->inventory = std::move(resp);
1437 },
1438 "xyz.openbmc_project.ObjectMapper",
1439 "/xyz/openbmc_project/object_mapper",
1440 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", "/",
1441 int32_t(0), inventoryForSystems);
1442
1443 health->populate();
1444
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001445 getMainChassisId(asyncResp, [](const std::string &chassisId,
1446 std::shared_ptr<AsyncResp> aRsp) {
1447 aRsp->res.jsonValue["Links"]["Chassis"] = {
1448 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1449 });
Ed Tanous6c34de42018-08-29 13:37:36 -07001450 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -07001451 asyncResp,
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001452 [](const bool &asserted, const std::shared_ptr<AsyncResp> aRsp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001453 if (asserted)
1454 {
1455 // If led group is asserted, then another call is needed to
1456 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -07001457 getLedIdentify(
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001458 aRsp, [](const std::string &ledStatus,
1459 const std::shared_ptr<AsyncResp> aRsp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001460 if (!ledStatus.empty())
1461 {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001462 aRsp->res.jsonValue["IndicatorLED"] = ledStatus;
Ed Tanous1abe55e2018-09-05 08:30:59 -07001463 }
1464 });
1465 }
1466 else
1467 {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001468 aRsp->res.jsonValue["IndicatorLED"] = "Off";
Ed Tanous1abe55e2018-09-05 08:30:59 -07001469 }
1470 });
James Feist5bc2dc82019-10-22 14:33:16 -07001471 getComputerSystem(asyncResp, health);
Ed Tanous6c34de42018-08-29 13:37:36 -07001472 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301473 getBootProperties(asyncResp);
Jason M. Billsf5c9f8b2018-12-18 16:51:18 -08001474 getPCIeDeviceList(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001475 }
1476
Ed Tanous1abe55e2018-09-05 08:30:59 -07001477 void doPatch(crow::Response &res, const crow::Request &req,
1478 const std::vector<std::string> &params) override
1479 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301480 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301481 std::optional<nlohmann::json> bootProps;
Santosh Puranik41352c22019-07-03 05:35:49 -05001482 auto asyncResp = std::make_shared<AsyncResp>(res);
1483
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001484 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
1485 bootProps))
Ed Tanous66173382018-08-15 18:20:59 -07001486 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001487 return;
1488 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301489
Johnathan Mantey944ffaf2019-08-12 16:16:14 -07001490 res.result(boost::beast::http::status::no_content);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301491 if (bootProps)
1492 {
1493 std::optional<std::string> bootSource;
1494 std::optional<std::string> bootEnable;
1495
1496 if (!json_util::readJson(*bootProps, asyncResp->res,
1497 "BootSourceOverrideTarget", bootSource,
1498 "BootSourceOverrideEnabled", bootEnable))
1499 {
1500 return;
1501 }
1502 setBootProperties(asyncResp, std::move(bootSource),
1503 std::move(bootEnable));
1504 }
Johnathan Mantey265c1602019-08-08 11:02:51 -07001505
Ed Tanous9712f8a2018-09-21 13:38:49 -07001506 if (indicatorLed)
1507 {
1508 std::string dbusLedState;
Jennifer Leed573bb22019-04-10 13:49:51 -07001509 if (*indicatorLed == "Lit")
Ed Tanous66173382018-08-15 18:20:59 -07001510 {
Jennifer Leed573bb22019-04-10 13:49:51 -07001511 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.On";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001512 }
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001513 else if (*indicatorLed == "Blinking")
Ed Tanous9712f8a2018-09-21 13:38:49 -07001514 {
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001515 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Blink";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001516 }
1517 else if (*indicatorLed == "Off")
1518 {
1519 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -07001520 }
1521 else
1522 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -08001523 messages::propertyValueNotInList(res, *indicatorLed,
1524 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -07001525 return;
1526 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001527
Ed Tanous9712f8a2018-09-21 13:38:49 -07001528 // Update led group
1529 BMCWEB_LOG_DEBUG << "Update led group.";
1530 crow::connections::systemBus->async_method_call(
Santosh Puranikcde19e52019-02-20 00:10:56 +05301531 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001532 if (ec)
1533 {
1534 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001535 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001536 return;
1537 }
1538 BMCWEB_LOG_DEBUG << "Led group update done.";
1539 },
1540 "xyz.openbmc_project.LED.GroupManager",
1541 "/xyz/openbmc_project/led/groups/enclosure_identify",
1542 "org.freedesktop.DBus.Properties", "Set",
1543 "xyz.openbmc_project.Led.Group", "Asserted",
Ed Tanousabf2add2019-01-22 16:40:12 -08001544 std::variant<bool>(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001545 (dbusLedState !=
1546 "xyz.openbmc_project.Led.Physical.Action.Off")));
1547
Ed Tanous9712f8a2018-09-21 13:38:49 -07001548 // Update identify led status
1549 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
1550 crow::connections::systemBus->async_method_call(
Johnathan Mantey265c1602019-08-08 11:02:51 -07001551 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001552 if (ec)
1553 {
1554 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001555 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001556 return;
1557 }
1558 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001559 },
1560 "xyz.openbmc_project.LED.Controller.identify",
1561 "/xyz/openbmc_project/led/physical/identify",
1562 "org.freedesktop.DBus.Properties", "Set",
1563 "xyz.openbmc_project.Led.Physical", "State",
Ed Tanousabf2add2019-01-22 16:40:12 -08001564 std::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001565 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001566 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001567};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001568} // namespace redfish