blob: 737aa3a547d098b056fea5ba06cd461e789bd406 [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
Ed Tanous9712f8a2018-09-21 13:38:49 -070018#include <boost/container/flat_map.hpp>
19#include <node.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020020#include <utils/json_utils.hpp>
Ed Tanousabf2add2019-01-22 16:40:12 -080021#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020022
Ed Tanous1abe55e2018-09-05 08:30:59 -070023namespace redfish
24{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020025
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020026/**
Ed Tanous6c34de42018-08-29 13:37:36 -070027 * @brief Retrieves computer system properties over dbus
28 *
29 * @param[in] aResp Shared pointer for completing asynchronous calls
30 * @param[in] name Computer system name from request
31 *
32 * @return None.
33 */
Ed Tanous029573d2019-02-01 10:57:49 -080034void getComputerSystem(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -070035{
Ed Tanous6c34de42018-08-29 13:37:36 -070036 BMCWEB_LOG_DEBUG << "Get available system components.";
37 crow::connections::systemBus->async_method_call(
Ed Tanous029573d2019-02-01 10:57:49 -080038 [aResp{std::move(aResp)}](
Ed Tanous6c34de42018-08-29 13:37:36 -070039 const boost::system::error_code ec,
40 const std::vector<std::pair<
41 std::string,
42 std::vector<std::pair<std::string, std::vector<std::string>>>>>
43 &subtree) {
44 if (ec)
45 {
46 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -070047 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -070048 return;
49 }
Ed Tanous6c34de42018-08-29 13:37:36 -070050 // Iterate over all retrieved ObjectPaths.
51 for (const std::pair<std::string,
52 std::vector<std::pair<
53 std::string, std::vector<std::string>>>>
54 &object : subtree)
55 {
56 const std::string &path = object.first;
57 BMCWEB_LOG_DEBUG << "Got path: " << path;
58 const std::vector<
59 std::pair<std::string, std::vector<std::string>>>
60 &connectionNames = object.second;
61 if (connectionNames.size() < 1)
62 {
63 continue;
64 }
Ed Tanous029573d2019-02-01 10:57:49 -080065
66 // This is not system, so check if it's cpu, dimm, UUID or
67 // BiosVer
68 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -070069 {
Ed Tanous029573d2019-02-01 10:57:49 -080070 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -070071 {
Ed Tanous029573d2019-02-01 10:57:49 -080072 if (interfaceName ==
73 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -070074 {
Ed Tanous029573d2019-02-01 10:57:49 -080075 BMCWEB_LOG_DEBUG
76 << "Found Dimm, now get its properties.";
77 crow::connections::systemBus->async_method_call(
78 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -070079 const std::vector<
80 std::pair<std::string, VariantType>>
81 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -080082 if (ec)
83 {
84 BMCWEB_LOG_ERROR
85 << "DBUS response error " << ec;
86 messages::internalError(aResp->res);
87 return;
88 }
89 BMCWEB_LOG_DEBUG << "Got "
90 << properties.size()
91 << "Dimm properties.";
92 for (const std::pair<std::string,
93 VariantType>
94 &property : properties)
95 {
96 if (property.first == "MemorySizeInKb")
Ed Tanous6c34de42018-08-29 13:37:36 -070097 {
Ed Tanous029573d2019-02-01 10:57:49 -080098 const uint64_t *value =
99 sdbusplus::message::variant_ns::
100 get_if<uint64_t>(
101 &property.second);
102 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700103 {
Ed Tanous029573d2019-02-01 10:57:49 -0800104 aResp->res.jsonValue
105 ["TotalSystemMemoryGi"
106 "B"] +=
107 *value / (1024 * 1024);
108 aResp->res
109 .jsonValue["MemorySummary"]
110 ["Status"]
111 ["State"] =
112 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700113 }
114 }
Ed Tanous029573d2019-02-01 10:57:49 -0800115 }
116 },
117 connection.first, path,
118 "org.freedesktop.DBus.Properties", "GetAll",
119 "xyz.openbmc_project.Inventory.Item.Dimm");
120 }
121 else if (interfaceName ==
122 "xyz.openbmc_project.Inventory.Item.Cpu")
123 {
124 BMCWEB_LOG_DEBUG
125 << "Found Cpu, now get its properties.";
126 crow::connections::systemBus->async_method_call(
127 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700128 const std::vector<
129 std::pair<std::string, VariantType>>
130 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800131 if (ec)
132 {
133 BMCWEB_LOG_ERROR
134 << "DBUS response error " << ec;
135 messages::internalError(aResp->res);
136 return;
137 }
138 BMCWEB_LOG_DEBUG << "Got "
139 << properties.size()
140 << "Cpu properties.";
141 for (const auto &property : properties)
142 {
143 if (property.first == "ProcessorFamily")
Ed Tanous6c34de42018-08-29 13:37:36 -0700144 {
Ed Tanous029573d2019-02-01 10:57:49 -0800145 const std::string *value =
146 sdbusplus::message::variant_ns::
147 get_if<std::string>(
148 &property.second);
149 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700150 {
Ed Tanous029573d2019-02-01 10:57:49 -0800151 nlohmann::json &procSummary =
152 aResp->res.jsonValue
153 ["ProcessorSumm"
154 "ary"];
155 nlohmann::json &procCount =
156 procSummary["Count"];
Ed Tanous04a258f2018-10-15 08:00:41 -0700157
Ed Tanous029573d2019-02-01 10:57:49 -0800158 procCount =
159 procCount.get<int>() + 1;
160 procSummary["Status"]["State"] =
161 "Enabled";
162 procSummary["Model"] = *value;
Ed Tanous6c34de42018-08-29 13:37:36 -0700163 }
164 }
Ed Tanous029573d2019-02-01 10:57:49 -0800165 }
166 },
167 connection.first, path,
168 "org.freedesktop.DBus.Properties", "GetAll",
169 "xyz.openbmc_project.Inventory.Item.Cpu");
170 }
171 else if (interfaceName ==
172 "xyz.openbmc_project.Common.UUID")
173 {
174 BMCWEB_LOG_DEBUG
175 << "Found UUID, now get its properties.";
176 crow::connections::systemBus->async_method_call(
177 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700178 const std::vector<
179 std::pair<std::string, VariantType>>
180 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800181 if (ec)
182 {
183 BMCWEB_LOG_DEBUG
184 << "DBUS response error " << ec;
185 messages::internalError(aResp->res);
186 return;
187 }
188 BMCWEB_LOG_DEBUG << "Got "
189 << properties.size()
190 << "UUID properties.";
191 for (const std::pair<std::string,
192 VariantType>
193 &property : properties)
194 {
195 if (property.first == "BIOSVer")
Ed Tanous6c34de42018-08-29 13:37:36 -0700196 {
Ed Tanous029573d2019-02-01 10:57:49 -0800197 const std::string *value =
198 sdbusplus::message::variant_ns::
199 get_if<std::string>(
200 &property.second);
201 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700202 {
Ed Tanous029573d2019-02-01 10:57:49 -0800203 aResp->res
204 .jsonValue["BiosVersion"] =
205 *value;
Ed Tanous6c34de42018-08-29 13:37:36 -0700206 }
Ed Tanous029573d2019-02-01 10:57:49 -0800207 }
208 if (property.first == "UUID")
209 {
210 const std::string *value =
211 sdbusplus::message::variant_ns::
212 get_if<std::string>(
213 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700214
Ed Tanous029573d2019-02-01 10:57:49 -0800215 if (value != nullptr)
216 {
217 std::string valueStr = *value;
218 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700219 {
Ed Tanous029573d2019-02-01 10:57:49 -0800220 valueStr.insert(8, 1, '-');
221 valueStr.insert(13, 1, '-');
222 valueStr.insert(18, 1, '-');
223 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700224 }
Ed Tanous029573d2019-02-01 10:57:49 -0800225 BMCWEB_LOG_DEBUG << "UUID = "
226 << valueStr;
227 aResp->res.jsonValue["UUID"] =
228 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700229 }
230 }
Ed Tanous029573d2019-02-01 10:57:49 -0800231 }
232 },
233 connection.first, path,
234 "org.freedesktop.DBus.Properties", "GetAll",
235 "xyz.openbmc_project.Common.UUID");
236 }
237 else if (interfaceName ==
238 "xyz.openbmc_project.Inventory.Item.System")
239 {
240 crow::connections::systemBus->async_method_call(
241 [aResp](const boost::system::error_code ec,
242 const std::vector<
243 std::pair<std::string, VariantType>>
244 &propertiesList) {
245 if (ec)
246 {
247 BMCWEB_LOG_ERROR
248 << "DBUS response error: " << ec;
249 messages::internalError(aResp->res);
250 return;
251 }
252 BMCWEB_LOG_DEBUG << "Got "
253 << propertiesList.size()
254 << "properties for system";
255 for (const std::pair<std::string,
256 VariantType>
257 &property : propertiesList)
258 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600259 const std::string &propertyName =
260 property.first;
261 if ((propertyName == "PartNumber") ||
262 (propertyName == "SerialNumber") ||
263 (propertyName == "Manufacturer") ||
264 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800265 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600266 const std::string *value =
267 std::get_if<std::string>(
268 &property.second);
269 if (value != nullptr)
270 {
271 aResp->res
272 .jsonValue[propertyName] =
273 *value;
274 }
Ed Tanous029573d2019-02-01 10:57:49 -0800275 }
276 }
277 aResp->res.jsonValue["Name"] = "system";
278 aResp->res.jsonValue["Id"] =
279 aResp->res.jsonValue["SerialNumber"];
280 },
281 connection.first, path,
282 "org.freedesktop.DBus.Properties", "GetAll",
283 "xyz.openbmc_project.Inventory.Decorator."
284 "Asset");
Ed Tanous6c34de42018-08-29 13:37:36 -0700285 }
286 }
287 }
288 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700289 },
290 "xyz.openbmc_project.ObjectMapper",
291 "/xyz/openbmc_project/object_mapper",
292 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700293 "/xyz/openbmc_project/inventory", int32_t(0),
294 std::array<const char *, 5>{
295 "xyz.openbmc_project.Inventory.Decorator.Asset",
296 "xyz.openbmc_project.Inventory.Item.Cpu",
297 "xyz.openbmc_project.Inventory.Item.Dimm",
298 "xyz.openbmc_project.Inventory.Item.System",
299 "xyz.openbmc_project.Common.UUID",
300 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700301}
302
303/**
304 * @brief Retrieves identify led group properties over dbus
305 *
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530306 * @param[in] aResp Shared pointer for generating response message.
Ed Tanous6c34de42018-08-29 13:37:36 -0700307 * @param[in] callback Callback for process retrieved data.
308 *
309 * @return None.
310 */
311template <typename CallbackFunc>
312void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
313 CallbackFunc &&callback)
314{
315 BMCWEB_LOG_DEBUG << "Get led groups";
316 crow::connections::systemBus->async_method_call(
317 [aResp{std::move(aResp)},
Ed Tanous66173382018-08-15 18:20:59 -0700318 callback{std::move(callback)}](const boost::system::error_code &ec,
319 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700320 if (ec)
321 {
322 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700323 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700324 return;
325 }
326 BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
327 for (const auto &objPath : resp)
328 {
329 const std::string &path = objPath.first;
330 if (path.rfind("enclosure_identify") != std::string::npos)
331 {
332 for (const auto &interface : objPath.second)
333 {
334 if (interface.first == "xyz.openbmc_project.Led.Group")
335 {
336 for (const auto &property : interface.second)
337 {
338 if (property.first == "Asserted")
339 {
340 const bool *asserted =
Ed Tanousabf2add2019-01-22 16:40:12 -0800341 std::get_if<bool>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700342 if (nullptr != asserted)
343 {
344 callback(*asserted, aResp);
345 }
346 else
347 {
348 callback(false, aResp);
349 }
350 }
351 }
352 }
353 }
354 }
355 }
356 },
357 "xyz.openbmc_project.LED.GroupManager",
358 "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
359 "GetManagedObjects");
360}
361
362template <typename CallbackFunc>
363void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
364{
365 BMCWEB_LOG_DEBUG << "Get identify led properties";
366 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700367 [aResp,
368 callback{std::move(callback)}](const boost::system::error_code ec,
369 const PropertiesType &properties) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700370 if (ec)
371 {
372 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700373 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700374 return;
375 }
376 BMCWEB_LOG_DEBUG << "Got " << properties.size()
377 << "led properties.";
378 std::string output;
379 for (const auto &property : properties)
380 {
381 if (property.first == "State")
382 {
383 const std::string *s =
Ed Tanousabf2add2019-01-22 16:40:12 -0800384 std::get_if<std::string>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700385 if (nullptr != s)
386 {
387 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
388 const auto pos = s->rfind('.');
389 if (pos != std::string::npos)
390 {
391 auto led = s->substr(pos + 1);
392 for (const std::pair<const char *, const char *>
393 &p :
394 std::array<
395 std::pair<const char *, const char *>, 3>{
396 {{"On", "Lit"},
397 {"Blink", "Blinking"},
398 {"Off", "Off"}}})
399 {
400 if (led == p.first)
401 {
402 output = p.second;
403 }
404 }
405 }
406 }
407 }
408 }
409 callback(output, aResp);
410 },
411 "xyz.openbmc_project.LED.Controller.identify",
412 "/xyz/openbmc_project/led/physical/identify",
413 "org.freedesktop.DBus.Properties", "GetAll",
414 "xyz.openbmc_project.Led.Physical");
415}
416
417/**
418 * @brief Retrieves host state properties over dbus
419 *
420 * @param[in] aResp Shared pointer for completing asynchronous calls.
421 *
422 * @return None.
423 */
424void getHostState(std::shared_ptr<AsyncResp> aResp)
425{
426 BMCWEB_LOG_DEBUG << "Get host information.";
427 crow::connections::systemBus->async_method_call(
Ed Tanousabf2add2019-01-22 16:40:12 -0800428 [aResp{std::move(aResp)}](const boost::system::error_code ec,
429 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700430 if (ec)
431 {
432 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700433 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700434 return;
435 }
Ed Tanous66173382018-08-15 18:20:59 -0700436
Ed Tanousabf2add2019-01-22 16:40:12 -0800437 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700438 BMCWEB_LOG_DEBUG << "Host state: " << *s;
439 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700440 {
Ed Tanous66173382018-08-15 18:20:59 -0700441 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800442 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700443 {
Ed Tanous66173382018-08-15 18:20:59 -0700444 aResp->res.jsonValue["PowerState"] = "On";
445 aResp->res.jsonValue["Status"]["State"] = "Enabled";
446 }
447 else
448 {
449 aResp->res.jsonValue["PowerState"] = "Off";
450 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700451 }
452 }
453 },
454 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700455 "org.freedesktop.DBus.Properties", "Get",
456 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700457}
458
459/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530460 * @brief Traslates boot source DBUS property value to redfish.
461 *
462 * @param[in] dbusSource The boot source in DBUS speak.
463 *
464 * @return Returns as a string, the boot source in Redfish terms. If translation
465 * cannot be done, returns an empty string.
466 */
467static std::string dbusToRfBootSource(const std::string &dbusSource)
468{
469 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
470 {
471 return "None";
472 }
473 else if (dbusSource ==
474 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
475 {
476 return "Hdd";
477 }
478 else if (dbusSource ==
479 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
480 {
481 return "Cd";
482 }
483 else if (dbusSource ==
484 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
485 {
486 return "Pxe";
487 }
488 else
489 {
490 return "";
491 }
492}
493
494/**
495 * @brief Traslates boot mode DBUS property value to redfish.
496 *
497 * @param[in] dbusMode The boot mode in DBUS speak.
498 *
499 * @return Returns as a string, the boot mode in Redfish terms. If translation
500 * cannot be done, returns an empty string.
501 */
502static std::string dbusToRfBootMode(const std::string &dbusMode)
503{
504 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
505 {
506 return "None";
507 }
508 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
509 {
510 return "Diags";
511 }
512 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
513 {
514 return "BiosSetup";
515 }
516 else
517 {
518 return "";
519 }
520}
521
522/**
523 * @brief Traslates boot source from Redfish to DBUS property value.
524 *
525 * @param[in] rfSource The boot source in Redfish.
526 *
527 * @return Returns as a string, the boot source as expected by DBUS.
528 * If translation cannot be done, returns an empty string.
529 */
530static std::string rfToDbusBootSource(const std::string &rfSource)
531{
532 if (rfSource == "None")
533 {
534 return "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
535 }
536 else if (rfSource == "Hdd")
537 {
538 return "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
539 }
540 else if (rfSource == "Cd")
541 {
542 return "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
543 }
544 else if (rfSource == "Pxe")
545 {
546 return "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
547 }
548 else
549 {
550 return "";
551 }
552}
553
554/**
555 * @brief Traslates boot mode from Redfish to DBUS property value.
556 *
557 * @param[in] rfMode The boot mode in Redfish.
558 *
559 * @return Returns as a string, the boot mode as expected by DBUS.
560 * If translation cannot be done, returns an empty string.
561 */
562static std::string rfToDbusBootMode(const std::string &rfMode)
563{
564 if (rfMode == "None")
565 {
566 return "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
567 }
568 else if (rfMode == "Diags")
569 {
570 return "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
571 }
572 else if (rfMode == "BiosSetup")
573 {
574 return "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
575 }
576 else
577 {
578 return "";
579 }
580}
581
582/**
583 * @brief Retrieves boot mode over DBUS and fills out the response
584 *
585 * @param[in] aResp Shared pointer for generating response message.
586 * @param[in] bootDbusObj The dbus object to query for boot properties.
587 *
588 * @return None.
589 */
590static void getBootMode(std::shared_ptr<AsyncResp> aResp,
591 std::string bootDbusObj)
592{
593 crow::connections::systemBus->async_method_call(
594 [aResp](const boost::system::error_code ec,
595 const std::variant<std::string> &bootMode) {
596 if (ec)
597 {
598 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
599 messages::internalError(aResp->res);
600 return;
601 }
602
603 const std::string *bootModeStr =
604 std::get_if<std::string>(&bootMode);
605
606 if (!bootModeStr)
607 {
608 messages::internalError(aResp->res);
609 return;
610 }
611
612 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
613
614 // TODO (Santosh): Do we need to support override mode?
615 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
616 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
617 "AllowableValues"] = {
618 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup"};
619
620 if (*bootModeStr !=
621 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
622 {
623 auto rfMode = dbusToRfBootMode(*bootModeStr);
624 if (!rfMode.empty())
625 {
626 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
627 rfMode;
628 }
629 }
630
631 // If the BootSourceOverrideTarget is still "None" at the end,
632 // reset the BootSourceOverrideEnabled to indicate that
633 // overrides are disabled
634 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
635 "None")
636 {
637 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
638 "Disabled";
639 }
640 },
641 "xyz.openbmc_project.Settings", bootDbusObj,
642 "org.freedesktop.DBus.Properties", "Get",
643 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
644}
645
646/**
647 * @brief Retrieves boot source over DBUS
648 *
649 * @param[in] aResp Shared pointer for generating response message.
650 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
651 *
652 * @return None.
653 */
654static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
655{
656 std::string bootDbusObj =
657 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
658 : "/xyz/openbmc_project/control/host0/boot";
659
660 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
661 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
662 (oneTimeEnabled) ? "Once" : "Continuous";
663
664 crow::connections::systemBus->async_method_call(
665 [aResp, bootDbusObj](const boost::system::error_code ec,
666 const std::variant<std::string> &bootSource) {
667 if (ec)
668 {
669 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
670 messages::internalError(aResp->res);
671 return;
672 }
673
674 const std::string *bootSourceStr =
675 std::get_if<std::string>(&bootSource);
676
677 if (!bootSourceStr)
678 {
679 messages::internalError(aResp->res);
680 return;
681 }
682 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
683
684 auto rfSource = dbusToRfBootSource(*bootSourceStr);
685 if (!rfSource.empty())
686 {
687 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
688 rfSource;
689 }
690 },
691 "xyz.openbmc_project.Settings", bootDbusObj,
692 "org.freedesktop.DBus.Properties", "Get",
693 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
694 getBootMode(std::move(aResp), std::move(bootDbusObj));
695}
696
697/**
698 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
699 * get boot source and boot mode.
700 *
701 * @param[in] aResp Shared pointer for generating response message.
702 *
703 * @return None.
704 */
705static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
706{
707 BMCWEB_LOG_DEBUG << "Get boot information.";
708
709 crow::connections::systemBus->async_method_call(
710 [aResp{std::move(aResp)}](
711 const boost::system::error_code ec,
712 const sdbusplus::message::variant<bool> &oneTime) {
713 if (ec)
714 {
715 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
716 messages::internalError(aResp->res);
717 return;
718 }
719
720 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
721
722 if (!oneTimePtr)
723 {
724 messages::internalError(aResp->res);
725 return;
726 }
727 getBootSource(aResp, *oneTimePtr);
728 },
729 "xyz.openbmc_project.Settings",
730 "/xyz/openbmc_project/control/host0/boot/one_time",
731 "org.freedesktop.DBus.Properties", "Get",
732 "xyz.openbmc_project.Object.Enable", "Enabled");
733}
734
735/**
736 * @brief Sets boot properties into DBUS object(s).
737 *
738 * @param[in] aResp Shared pointer for generating response message.
739 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
740 * @param[in] bootSource The boot source to set.
741 * @param[in] bootEnable The source override "enable" to set.
742 *
743 * @return None.
744 */
745static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
746 bool oneTimeEnabled,
747 std::optional<std::string> bootSource,
748 std::optional<std::string> bootEnable)
749{
750 if (bootEnable && (bootEnable != "Once") && (bootEnable != "Continuous") &&
751 (bootEnable != "Disabled"))
752 {
753 BMCWEB_LOG_DEBUG << "Unsupported value for BootSourceOverrideEnabled: "
754 << *bootEnable;
755 messages::propertyValueNotInList(aResp->res, *bootEnable,
756 "BootSourceOverrideEnabled");
757 return;
758 }
759
760 bool oneTimeSetting = oneTimeEnabled;
761 // Validate incoming parameters
762 if (bootEnable)
763 {
764 if (*bootEnable == "Once")
765 {
766 oneTimeSetting = true;
767 }
768 else if (*bootEnable == "Continuous")
769 {
770 oneTimeSetting = false;
771 }
772 else if (*bootEnable == "Disabled")
773 {
774 oneTimeSetting = false;
775 }
776 else
777 {
778
779 BMCWEB_LOG_DEBUG << "Unsupported value for "
780 "BootSourceOverrideEnabled: "
781 << *bootEnable;
782 messages::propertyValueNotInList(aResp->res, *bootEnable,
783 "BootSourceOverrideEnabled");
784 return;
785 }
786 }
787 std::string bootSourceStr;
788 std::string bootModeStr;
789 if (bootSource)
790 {
791 bootSourceStr = rfToDbusBootSource(*bootSource);
792 bootModeStr = rfToDbusBootMode(*bootSource);
793
794 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
795 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
796
797 if (bootSourceStr.empty() && bootModeStr.empty())
798 {
799 BMCWEB_LOG_DEBUG << "Invalid property value for "
800 "BootSourceOverrideTarget: "
801 << *bootSource;
802 messages::propertyValueNotInList(aResp->res, *bootSource,
803 "BootSourceTargetOverride");
804 return;
805 }
806 }
807 const char *bootObj =
808 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
809 : "/xyz/openbmc_project/control/host0/boot";
810 // Figure out what properties to set
811 if (bootEnable && (*bootEnable == "Disabled"))
812 {
813 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
814 // Request to only turn OFF/ON enabled, if turning enabled OFF, need
815 // to reset the source and mode too. If turning it ON, we only need
816 // to set the enabled property
817 bootSourceStr =
818 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
819 bootModeStr = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
820 }
821 else if (bootSource)
822 {
823 // Source target specified
824 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
825 // Figure out which DBUS interface and property to use
826 bootSourceStr = rfToDbusBootSource(*bootSource);
827 bootModeStr = rfToDbusBootMode(*bootSource);
828
829 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
830 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
831
832 if (bootSourceStr.empty() && bootModeStr.empty())
833 {
834 BMCWEB_LOG_DEBUG << "Invalid property value for "
835 "BootSourceOverrideTarget: "
836 << *bootSource;
837 messages::propertyValueNotInList(aResp->res, *bootSource,
838 "BootSourceTargetOverride");
839 return;
840 }
841
842 if (!bootSourceStr.empty())
843 {
844 // If setting to anything other than default, also reset boot
845 // mode property
846 if (bootSourceStr !=
847 "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
848 {
849 bootModeStr =
850 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
851 }
852 }
853 else // if (!bootModeStr.empty())
854 {
855 // If setting to anything other than default, also reset boot
856 // source property
857 if (bootModeStr !=
858 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
859 {
860 bootSourceStr =
861 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
862 }
863 }
864 }
865 if (!bootSourceStr.empty())
866 {
867 crow::connections::systemBus->async_method_call(
868 [aResp](const boost::system::error_code ec) {
869 if (ec)
870 {
871 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
872 messages::internalError(aResp->res);
873 return;
874 }
875 BMCWEB_LOG_DEBUG << "Boot source update done.";
876 },
877 "xyz.openbmc_project.Settings", bootObj,
878 "org.freedesktop.DBus.Properties", "Set",
879 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
880 std::variant<std::string>(bootSourceStr));
881 }
882 if (!bootModeStr.empty())
883 {
884 crow::connections::systemBus->async_method_call(
885 [aResp](const boost::system::error_code ec) {
886 if (ec)
887 {
888 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
889 messages::internalError(aResp->res);
890 return;
891 }
892 BMCWEB_LOG_DEBUG << "Boot mode update done.";
893 },
894 "xyz.openbmc_project.Settings", bootObj,
895 "org.freedesktop.DBus.Properties", "Set",
896 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
897 std::variant<std::string>(bootModeStr));
898 }
899 crow::connections::systemBus->async_method_call(
900 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
901 if (ec)
902 {
903 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
904 messages::internalError(aResp->res);
905 return;
906 }
907 BMCWEB_LOG_DEBUG << "Boot enable update done.";
908 },
909 "xyz.openbmc_project.Settings",
910 "/xyz/openbmc_project/control/host0/boot/one_time",
911 "org.freedesktop.DBus.Properties", "Set",
912 "xyz.openbmc_project.Object.Enable", "Enabled",
913 std::variant<bool>(oneTimeSetting));
914}
915
916/**
917 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
918 * set boot source/boot mode properties.
919 *
920 * @param[in] aResp Shared pointer for generating response message.
921 * @param[in] bootSource The boot source from incoming RF request.
922 * @param[in] bootEnable The boot override enable from incoming RF request.
923 *
924 * @return None.
925 */
926static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
927 std::optional<std::string> bootSource,
928 std::optional<std::string> bootEnable)
929{
930 BMCWEB_LOG_DEBUG << "Set boot information.";
931
932 crow::connections::systemBus->async_method_call(
933 [aResp{std::move(aResp)}, bootSource{std::move(bootSource)},
934 bootEnable{std::move(bootEnable)}](
935 const boost::system::error_code ec,
936 const sdbusplus::message::variant<bool> &oneTime) {
937 if (ec)
938 {
939 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
940 messages::internalError(aResp->res);
941 return;
942 }
943
944 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
945
946 if (!oneTimePtr)
947 {
948 messages::internalError(aResp->res);
949 return;
950 }
951
952 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
953
954 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
955 std::move(bootEnable));
956 },
957 "xyz.openbmc_project.Settings",
958 "/xyz/openbmc_project/control/host0/boot/one_time",
959 "org.freedesktop.DBus.Properties", "Get",
960 "xyz.openbmc_project.Object.Enable", "Enabled");
961}
962
963/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200964 * SystemsCollection derived class for delivering ComputerSystems Collection
965 * Schema
966 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700967class SystemsCollection : public Node
968{
969 public:
970 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
971 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700972 entityPrivileges = {
973 {boost::beast::http::verb::get, {{"Login"}}},
974 {boost::beast::http::verb::head, {{"Login"}}},
975 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
976 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
977 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
978 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
979 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200980
Ed Tanous1abe55e2018-09-05 08:30:59 -0700981 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700982 void doGet(crow::Response &res, const crow::Request &req,
983 const std::vector<std::string> &params) override
984 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800985 res.jsonValue["@odata.type"] =
986 "#ComputerSystemCollection.ComputerSystemCollection";
987 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
988 res.jsonValue["@odata.context"] =
989 "/redfish/v1/"
990 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
991 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -0800992 res.jsonValue["Members"] = {
993 {{"@odata.id", "/redfish/v1/Systems/system"}}};
994 res.jsonValue["Members@odata.count"] = 1;
995 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -0700996 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200997};
998
999/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001000 * SystemActionsReset class supports handle POST method for Reset action.
1001 * The class retrieves and sends data directly to D-Bus.
1002 */
1003class SystemActionsReset : public Node
1004{
1005 public:
1006 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001007 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001008 {
1009 entityPrivileges = {
1010 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1011 }
1012
1013 private:
1014 /**
1015 * Function handles POST method request.
1016 * Analyzes POST body message before sends Reset request data to D-Bus.
1017 */
1018 void doPost(crow::Response &res, const crow::Request &req,
1019 const std::vector<std::string> &params) override
1020 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001021 auto asyncResp = std::make_shared<AsyncResp>(res);
1022
1023 std::string resetType;
1024 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001025 {
1026 return;
1027 }
1028
Ed Tanous9712f8a2018-09-21 13:38:49 -07001029 if (resetType == "ForceOff")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001030 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001031 // Force off acts on the chassis
1032 crow::connections::systemBus->async_method_call(
1033 [asyncResp](const boost::system::error_code ec) {
1034 if (ec)
1035 {
1036 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001037 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001038 return;
1039 }
1040 // TODO Consider support polling mechanism to verify
1041 // status of host and chassis after execute the
1042 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -07001043 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001044 },
1045 "xyz.openbmc_project.State.Chassis",
1046 "/xyz/openbmc_project/state/chassis0",
1047 "org.freedesktop.DBus.Properties", "Set",
1048 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
Ed Tanousabf2add2019-01-22 16:40:12 -08001049 std::variant<std::string>{
Ed Tanous9712f8a2018-09-21 13:38:49 -07001050 "xyz.openbmc_project.State.Chassis.Transition.Off"});
1051 return;
Ed Tanouscc340dd2018-08-29 13:43:38 -07001052 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001053 // all other actions operate on the host
1054 std::string command;
1055 // Execute Reset Action regarding to each reset type.
1056 if (resetType == "On")
1057 {
1058 command = "xyz.openbmc_project.State.Host.Transition.On";
1059 }
1060 else if (resetType == "GracefulShutdown")
1061 {
1062 command = "xyz.openbmc_project.State.Host.Transition.Off";
1063 }
1064 else if (resetType == "GracefulRestart")
1065 {
1066 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
1067 }
1068 else
1069 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001070 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001071 return;
1072 }
1073
1074 crow::connections::systemBus->async_method_call(
1075 [asyncResp](const boost::system::error_code ec) {
1076 if (ec)
1077 {
1078 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001079 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001080 return;
1081 }
1082 // TODO Consider support polling mechanism to verify
1083 // status of host and chassis after execute the
1084 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -07001085 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001086 },
1087 "xyz.openbmc_project.State.Host",
1088 "/xyz/openbmc_project/state/host0",
1089 "org.freedesktop.DBus.Properties", "Set",
1090 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
Ed Tanousabf2add2019-01-22 16:40:12 -08001091 std::variant<std::string>{command});
Ed Tanouscc340dd2018-08-29 13:43:38 -07001092 }
1093};
1094
1095/**
Ed Tanous66173382018-08-15 18:20:59 -07001096 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001097 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001098class Systems : public Node
1099{
1100 public:
1101 /*
1102 * Default Constructor
1103 */
Ed Tanous029573d2019-02-01 10:57:49 -08001104 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001105 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001106 entityPrivileges = {
1107 {boost::beast::http::verb::get, {{"Login"}}},
1108 {boost::beast::http::verb::head, {{"Login"}}},
1109 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1110 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1111 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1112 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001113 }
1114
Ed Tanous1abe55e2018-09-05 08:30:59 -07001115 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001116 /**
1117 * Functions triggers appropriate requests on DBus
1118 */
1119 void doGet(crow::Response &res, const crow::Request &req,
1120 const std::vector<std::string> &params) override
1121 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301122 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001123 res.jsonValue["@odata.context"] =
1124 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001125 res.jsonValue["Name"] = "Computer System";
1126 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001127 res.jsonValue["SystemType"] = "Physical";
1128 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001129 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1130 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
1131 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
1132 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001133 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001134
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001135 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001136 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001137 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001138 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
1139
Ed Tanouscc340dd2018-08-29 13:43:38 -07001140 // TODO Need to support ForceRestart.
1141 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1142 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001143 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001144 {"ResetType@Redfish.AllowableValues",
1145 {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001146
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001147 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001148 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001149
Ed Tanousa0803ef2018-08-29 13:29:23 -07001150 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001151
Ed Tanous6c34de42018-08-29 13:37:36 -07001152 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -07001153 asyncResp,
1154 [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001155 if (asserted)
1156 {
1157 // If led group is asserted, then another call is needed to
1158 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -07001159 getLedIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -07001160 aResp, [](const std::string &ledStatus,
1161 const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001162 if (!ledStatus.empty())
1163 {
1164 aResp->res.jsonValue["IndicatorLED"] =
1165 ledStatus;
1166 }
1167 });
1168 }
1169 else
1170 {
1171 aResp->res.jsonValue["IndicatorLED"] = "Off";
1172 }
1173 });
Ed Tanous029573d2019-02-01 10:57:49 -08001174 getComputerSystem(asyncResp);
Ed Tanous6c34de42018-08-29 13:37:36 -07001175 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301176 getBootProperties(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001177 }
1178
Ed Tanous1abe55e2018-09-05 08:30:59 -07001179 void doPatch(crow::Response &res, const crow::Request &req,
1180 const std::vector<std::string> &params) override
1181 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301182 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301183 std::optional<nlohmann::json> bootProps;
1184 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
1185 bootProps))
Ed Tanous66173382018-08-15 18:20:59 -07001186 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001187 return;
1188 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301189
Ed Tanous029573d2019-02-01 10:57:49 -08001190 auto asyncResp = std::make_shared<AsyncResp>(res);
1191 messages::success(asyncResp->res);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301192
1193 if (bootProps)
1194 {
1195 std::optional<std::string> bootSource;
1196 std::optional<std::string> bootEnable;
1197
1198 if (!json_util::readJson(*bootProps, asyncResp->res,
1199 "BootSourceOverrideTarget", bootSource,
1200 "BootSourceOverrideEnabled", bootEnable))
1201 {
1202 return;
1203 }
1204 setBootProperties(asyncResp, std::move(bootSource),
1205 std::move(bootEnable));
1206 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001207 if (indicatorLed)
1208 {
1209 std::string dbusLedState;
1210 if (*indicatorLed == "On")
Ed Tanous66173382018-08-15 18:20:59 -07001211 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001212 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
1213 }
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001214 else if (*indicatorLed == "Blinking")
Ed Tanous9712f8a2018-09-21 13:38:49 -07001215 {
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001216 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Blink";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001217 }
1218 else if (*indicatorLed == "Off")
1219 {
1220 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -07001221 }
1222 else
1223 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -08001224 messages::propertyValueNotInList(res, *indicatorLed,
1225 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -07001226 return;
1227 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001228
1229 getHostState(asyncResp);
Ed Tanous029573d2019-02-01 10:57:49 -08001230 getComputerSystem(asyncResp);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001231
1232 // Update led group
1233 BMCWEB_LOG_DEBUG << "Update led group.";
1234 crow::connections::systemBus->async_method_call(
Santosh Puranikcde19e52019-02-20 00:10:56 +05301235 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001236 if (ec)
1237 {
1238 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001239 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001240 return;
1241 }
1242 BMCWEB_LOG_DEBUG << "Led group update done.";
1243 },
1244 "xyz.openbmc_project.LED.GroupManager",
1245 "/xyz/openbmc_project/led/groups/enclosure_identify",
1246 "org.freedesktop.DBus.Properties", "Set",
1247 "xyz.openbmc_project.Led.Group", "Asserted",
Ed Tanousabf2add2019-01-22 16:40:12 -08001248 std::variant<bool>(
Ed Tanous9712f8a2018-09-21 13:38:49 -07001249 (dbusLedState ==
1250 "xyz.openbmc_project.Led.Physical.Action.Off"
1251 ? false
1252 : true)));
1253 // Update identify led status
1254 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
1255 crow::connections::systemBus->async_method_call(
1256 [asyncResp{std::move(asyncResp)},
1257 indicatorLed{std::move(*indicatorLed)}](
1258 const boost::system::error_code ec) {
1259 if (ec)
1260 {
1261 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001262 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001263 return;
1264 }
1265 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001266 },
1267 "xyz.openbmc_project.LED.Controller.identify",
1268 "/xyz/openbmc_project/led/physical/identify",
1269 "org.freedesktop.DBus.Properties", "Set",
1270 "xyz.openbmc_project.Led.Physical", "State",
Ed Tanousabf2add2019-01-22 16:40:12 -08001271 std::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001272 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001273 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001274};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001275} // namespace redfish