blob: 6ea5f2e5b44a841672db1745eacef3bbedee5c3e [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
Jennifer Leec5d03ff2019-03-08 15:42:58 -080018#include "redfish_util.hpp"
19
Ed Tanous9712f8a2018-09-21 13:38:49 -070020#include <boost/container/flat_map.hpp>
21#include <node.hpp>
Andrew Geisslercb7e1e72019-02-19 13:05:38 -060022#include <utils/fw_utils.hpp>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020023#include <utils/json_utils.hpp>
Ed Tanousabf2add2019-01-22 16:40:12 -080024#include <variant>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020025
Ed Tanous1abe55e2018-09-05 08:30:59 -070026namespace redfish
27{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020028
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020029/**
Ed Tanous6c34de42018-08-29 13:37:36 -070030 * @brief Retrieves computer system properties over dbus
31 *
32 * @param[in] aResp Shared pointer for completing asynchronous calls
33 * @param[in] name Computer system name from request
34 *
35 * @return None.
36 */
Ed Tanous029573d2019-02-01 10:57:49 -080037void getComputerSystem(std::shared_ptr<AsyncResp> aResp)
Ed Tanous6c34de42018-08-29 13:37:36 -070038{
Ed Tanous6c34de42018-08-29 13:37:36 -070039 BMCWEB_LOG_DEBUG << "Get available system components.";
40 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -080041 [aResp](
Ed Tanous6c34de42018-08-29 13:37:36 -070042 const boost::system::error_code ec,
43 const std::vector<std::pair<
44 std::string,
45 std::vector<std::pair<std::string, std::vector<std::string>>>>>
46 &subtree) {
47 if (ec)
48 {
49 BMCWEB_LOG_DEBUG << "DBUS response error";
Jason M. Billsf12894f2018-10-09 12:45:45 -070050 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -070051 return;
52 }
Ed Tanous6c34de42018-08-29 13:37:36 -070053 // Iterate over all retrieved ObjectPaths.
54 for (const std::pair<std::string,
55 std::vector<std::pair<
56 std::string, std::vector<std::string>>>>
57 &object : subtree)
58 {
59 const std::string &path = object.first;
60 BMCWEB_LOG_DEBUG << "Got path: " << path;
61 const std::vector<
62 std::pair<std::string, std::vector<std::string>>>
63 &connectionNames = object.second;
64 if (connectionNames.size() < 1)
65 {
66 continue;
67 }
Ed Tanous029573d2019-02-01 10:57:49 -080068
69 // This is not system, so check if it's cpu, dimm, UUID or
70 // BiosVer
71 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -070072 {
Ed Tanous029573d2019-02-01 10:57:49 -080073 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -070074 {
Ed Tanous029573d2019-02-01 10:57:49 -080075 if (interfaceName ==
76 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -070077 {
Ed Tanous029573d2019-02-01 10:57:49 -080078 BMCWEB_LOG_DEBUG
79 << "Found Dimm, now get its properties.";
80 crow::connections::systemBus->async_method_call(
81 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -070082 const std::vector<
83 std::pair<std::string, VariantType>>
84 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -080085 if (ec)
86 {
87 BMCWEB_LOG_ERROR
88 << "DBUS response error " << ec;
89 messages::internalError(aResp->res);
90 return;
91 }
92 BMCWEB_LOG_DEBUG << "Got "
93 << properties.size()
94 << "Dimm properties.";
95 for (const std::pair<std::string,
96 VariantType>
97 &property : properties)
98 {
99 if (property.first == "MemorySizeInKb")
Ed Tanous6c34de42018-08-29 13:37:36 -0700100 {
Ed Tanous029573d2019-02-01 10:57:49 -0800101 const uint64_t *value =
102 sdbusplus::message::variant_ns::
103 get_if<uint64_t>(
104 &property.second);
105 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700106 {
Ed Tanous029573d2019-02-01 10:57:49 -0800107 aResp->res.jsonValue
108 ["TotalSystemMemoryGi"
109 "B"] +=
110 *value / (1024 * 1024);
111 aResp->res
112 .jsonValue["MemorySummary"]
113 ["Status"]
114 ["State"] =
115 "Enabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700116 }
117 }
Ed Tanous029573d2019-02-01 10:57:49 -0800118 }
119 },
120 connection.first, path,
121 "org.freedesktop.DBus.Properties", "GetAll",
122 "xyz.openbmc_project.Inventory.Item.Dimm");
123 }
124 else if (interfaceName ==
125 "xyz.openbmc_project.Inventory.Item.Cpu")
126 {
127 BMCWEB_LOG_DEBUG
128 << "Found Cpu, now get its properties.";
129 crow::connections::systemBus->async_method_call(
130 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700131 const std::vector<
132 std::pair<std::string, VariantType>>
133 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800134 if (ec)
135 {
136 BMCWEB_LOG_ERROR
137 << "DBUS response error " << ec;
138 messages::internalError(aResp->res);
139 return;
140 }
141 BMCWEB_LOG_DEBUG << "Got "
142 << properties.size()
143 << "Cpu properties.";
144 for (const auto &property : properties)
145 {
146 if (property.first == "ProcessorFamily")
Ed Tanous6c34de42018-08-29 13:37:36 -0700147 {
Ed Tanous029573d2019-02-01 10:57:49 -0800148 const std::string *value =
149 sdbusplus::message::variant_ns::
150 get_if<std::string>(
151 &property.second);
152 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700153 {
Ed Tanous029573d2019-02-01 10:57:49 -0800154 nlohmann::json &procSummary =
155 aResp->res.jsonValue
156 ["ProcessorSumm"
157 "ary"];
158 nlohmann::json &procCount =
159 procSummary["Count"];
Ed Tanous04a258f2018-10-15 08:00:41 -0700160
Ed Tanous029573d2019-02-01 10:57:49 -0800161 procCount =
162 procCount.get<int>() + 1;
163 procSummary["Status"]["State"] =
164 "Enabled";
165 procSummary["Model"] = *value;
Ed Tanous6c34de42018-08-29 13:37:36 -0700166 }
167 }
Ed Tanous029573d2019-02-01 10:57:49 -0800168 }
169 },
170 connection.first, path,
171 "org.freedesktop.DBus.Properties", "GetAll",
172 "xyz.openbmc_project.Inventory.Item.Cpu");
173 }
174 else if (interfaceName ==
175 "xyz.openbmc_project.Common.UUID")
176 {
177 BMCWEB_LOG_DEBUG
178 << "Found UUID, now get its properties.";
179 crow::connections::systemBus->async_method_call(
180 [aResp](const boost::system::error_code ec,
Ed Tanous6c34de42018-08-29 13:37:36 -0700181 const std::vector<
182 std::pair<std::string, VariantType>>
183 &properties) {
Ed Tanous029573d2019-02-01 10:57:49 -0800184 if (ec)
185 {
186 BMCWEB_LOG_DEBUG
187 << "DBUS response error " << ec;
188 messages::internalError(aResp->res);
189 return;
190 }
191 BMCWEB_LOG_DEBUG << "Got "
192 << properties.size()
193 << "UUID properties.";
194 for (const std::pair<std::string,
195 VariantType>
196 &property : properties)
197 {
Ed Tanous029573d2019-02-01 10:57:49 -0800198 if (property.first == "UUID")
199 {
200 const std::string *value =
201 sdbusplus::message::variant_ns::
202 get_if<std::string>(
203 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700204
Ed Tanous029573d2019-02-01 10:57:49 -0800205 if (value != nullptr)
206 {
207 std::string valueStr = *value;
208 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700209 {
Ed Tanous029573d2019-02-01 10:57:49 -0800210 valueStr.insert(8, 1, '-');
211 valueStr.insert(13, 1, '-');
212 valueStr.insert(18, 1, '-');
213 valueStr.insert(23, 1, '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700214 }
Ed Tanous029573d2019-02-01 10:57:49 -0800215 BMCWEB_LOG_DEBUG << "UUID = "
216 << valueStr;
217 aResp->res.jsonValue["UUID"] =
218 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700219 }
220 }
Ed Tanous029573d2019-02-01 10:57:49 -0800221 }
222 },
223 connection.first, path,
224 "org.freedesktop.DBus.Properties", "GetAll",
225 "xyz.openbmc_project.Common.UUID");
226 }
227 else if (interfaceName ==
228 "xyz.openbmc_project.Inventory.Item.System")
229 {
230 crow::connections::systemBus->async_method_call(
231 [aResp](const boost::system::error_code ec,
232 const std::vector<
233 std::pair<std::string, VariantType>>
234 &propertiesList) {
235 if (ec)
236 {
James Feiste4a4b9a2019-06-20 14:08:07 -0700237 // doesn't have to include this
238 // interface
Ed Tanous029573d2019-02-01 10:57:49 -0800239 return;
240 }
241 BMCWEB_LOG_DEBUG << "Got "
242 << propertiesList.size()
243 << "properties for system";
244 for (const std::pair<std::string,
245 VariantType>
246 &property : propertiesList)
247 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600248 const std::string &propertyName =
249 property.first;
250 if ((propertyName == "PartNumber") ||
251 (propertyName == "SerialNumber") ||
252 (propertyName == "Manufacturer") ||
253 (propertyName == "Model"))
Ed Tanous029573d2019-02-01 10:57:49 -0800254 {
beccabroekfc5afcf2019-03-05 14:35:15 -0600255 const std::string *value =
256 std::get_if<std::string>(
257 &property.second);
258 if (value != nullptr)
259 {
260 aResp->res
261 .jsonValue[propertyName] =
262 *value;
263 }
Ed Tanous029573d2019-02-01 10:57:49 -0800264 }
265 }
266 aResp->res.jsonValue["Name"] = "system";
267 aResp->res.jsonValue["Id"] =
268 aResp->res.jsonValue["SerialNumber"];
Andrew Geisslercb7e1e72019-02-19 13:05:38 -0600269 // Grab the bios version
270 fw_util::getActiveFwVersion(
271 aResp, fw_util::biosPurpose,
272 "BiosVersion");
Ed Tanous029573d2019-02-01 10:57:49 -0800273 },
274 connection.first, path,
275 "org.freedesktop.DBus.Properties", "GetAll",
276 "xyz.openbmc_project.Inventory.Decorator."
277 "Asset");
James Feiste4a4b9a2019-06-20 14:08:07 -0700278
279 crow::connections::systemBus->async_method_call(
280 [aResp](
281 const boost::system::error_code ec,
282 const std::variant<std::string> &property) {
283 if (ec)
284 {
285 // doesn't have to include this
286 // interface
287 return;
288 }
289
290 const std::string *value =
291 std::get_if<std::string>(&property);
292 if (value != nullptr)
293 {
294 aResp->res.jsonValue["AssetTag"] =
295 *value;
296 }
297 },
298 connection.first, path,
299 "org.freedesktop.DBus.Properties", "Get",
300 "xyz.openbmc_project.Inventory.Decorator."
301 "AssetTag",
302 "AssetTag");
Ed Tanous6c34de42018-08-29 13:37:36 -0700303 }
304 }
305 }
306 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700307 },
308 "xyz.openbmc_project.ObjectMapper",
309 "/xyz/openbmc_project/object_mapper",
310 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700311 "/xyz/openbmc_project/inventory", int32_t(0),
312 std::array<const char *, 5>{
313 "xyz.openbmc_project.Inventory.Decorator.Asset",
314 "xyz.openbmc_project.Inventory.Item.Cpu",
315 "xyz.openbmc_project.Inventory.Item.Dimm",
316 "xyz.openbmc_project.Inventory.Item.System",
317 "xyz.openbmc_project.Common.UUID",
318 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700319}
320
321/**
322 * @brief Retrieves identify led group properties over dbus
323 *
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530324 * @param[in] aResp Shared pointer for generating response message.
Ed Tanous6c34de42018-08-29 13:37:36 -0700325 * @param[in] callback Callback for process retrieved data.
326 *
327 * @return None.
328 */
329template <typename CallbackFunc>
330void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
331 CallbackFunc &&callback)
332{
333 BMCWEB_LOG_DEBUG << "Get led groups";
334 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800335 [aResp,
Ed Tanous66173382018-08-15 18:20:59 -0700336 callback{std::move(callback)}](const boost::system::error_code &ec,
337 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700338 if (ec)
339 {
340 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700341 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700342 return;
343 }
344 BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
345 for (const auto &objPath : resp)
346 {
347 const std::string &path = objPath.first;
348 if (path.rfind("enclosure_identify") != std::string::npos)
349 {
350 for (const auto &interface : objPath.second)
351 {
352 if (interface.first == "xyz.openbmc_project.Led.Group")
353 {
354 for (const auto &property : interface.second)
355 {
356 if (property.first == "Asserted")
357 {
358 const bool *asserted =
Ed Tanousabf2add2019-01-22 16:40:12 -0800359 std::get_if<bool>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700360 if (nullptr != asserted)
361 {
362 callback(*asserted, aResp);
363 }
364 else
365 {
366 callback(false, aResp);
367 }
368 }
369 }
370 }
371 }
372 }
373 }
374 },
375 "xyz.openbmc_project.LED.GroupManager",
376 "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
377 "GetManagedObjects");
378}
379
380template <typename CallbackFunc>
381void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
382{
383 BMCWEB_LOG_DEBUG << "Get identify led properties";
384 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700385 [aResp,
386 callback{std::move(callback)}](const boost::system::error_code ec,
387 const PropertiesType &properties) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700388 if (ec)
389 {
390 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700391 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700392 return;
393 }
394 BMCWEB_LOG_DEBUG << "Got " << properties.size()
395 << "led properties.";
396 std::string output;
397 for (const auto &property : properties)
398 {
399 if (property.first == "State")
400 {
401 const std::string *s =
Ed Tanousabf2add2019-01-22 16:40:12 -0800402 std::get_if<std::string>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700403 if (nullptr != s)
404 {
405 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
406 const auto pos = s->rfind('.');
407 if (pos != std::string::npos)
408 {
409 auto led = s->substr(pos + 1);
410 for (const std::pair<const char *, const char *>
411 &p :
412 std::array<
413 std::pair<const char *, const char *>, 3>{
414 {{"On", "Lit"},
415 {"Blink", "Blinking"},
416 {"Off", "Off"}}})
417 {
418 if (led == p.first)
419 {
420 output = p.second;
421 }
422 }
423 }
424 }
425 }
426 }
427 callback(output, aResp);
428 },
429 "xyz.openbmc_project.LED.Controller.identify",
430 "/xyz/openbmc_project/led/physical/identify",
431 "org.freedesktop.DBus.Properties", "GetAll",
432 "xyz.openbmc_project.Led.Physical");
433}
Ed Tanous6c34de42018-08-29 13:37:36 -0700434/**
435 * @brief Retrieves host state properties over dbus
436 *
437 * @param[in] aResp Shared pointer for completing asynchronous calls.
438 *
439 * @return None.
440 */
441void getHostState(std::shared_ptr<AsyncResp> aResp)
442{
443 BMCWEB_LOG_DEBUG << "Get host information.";
444 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800445 [aResp](const boost::system::error_code ec,
446 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700447 if (ec)
448 {
449 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700450 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700451 return;
452 }
Ed Tanous66173382018-08-15 18:20:59 -0700453
Ed Tanousabf2add2019-01-22 16:40:12 -0800454 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700455 BMCWEB_LOG_DEBUG << "Host state: " << *s;
456 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700457 {
Ed Tanous66173382018-08-15 18:20:59 -0700458 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800459 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700460 {
Ed Tanous66173382018-08-15 18:20:59 -0700461 aResp->res.jsonValue["PowerState"] = "On";
462 aResp->res.jsonValue["Status"]["State"] = "Enabled";
463 }
464 else
465 {
466 aResp->res.jsonValue["PowerState"] = "Off";
467 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700468 }
469 }
470 },
471 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700472 "org.freedesktop.DBus.Properties", "Get",
473 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700474}
475
476/**
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530477 * @brief Traslates boot source DBUS property value to redfish.
478 *
479 * @param[in] dbusSource The boot source in DBUS speak.
480 *
481 * @return Returns as a string, the boot source in Redfish terms. If translation
482 * cannot be done, returns an empty string.
483 */
484static std::string dbusToRfBootSource(const std::string &dbusSource)
485{
486 if (dbusSource == "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
487 {
488 return "None";
489 }
490 else if (dbusSource ==
491 "xyz.openbmc_project.Control.Boot.Source.Sources.Disk")
492 {
493 return "Hdd";
494 }
495 else if (dbusSource ==
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530496 "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia")
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530497 {
498 return "Cd";
499 }
500 else if (dbusSource ==
501 "xyz.openbmc_project.Control.Boot.Source.Sources.Network")
502 {
503 return "Pxe";
504 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700505 else if (dbusSource ==
506 "xyz.openbmc_project.Control.Boot.Source.Sources.Removable")
507 {
508 return "Usb";
509 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530510 else
511 {
512 return "";
513 }
514}
515
516/**
517 * @brief Traslates boot mode DBUS property value to redfish.
518 *
519 * @param[in] dbusMode The boot mode in DBUS speak.
520 *
521 * @return Returns as a string, the boot mode in Redfish terms. If translation
522 * cannot be done, returns an empty string.
523 */
524static std::string dbusToRfBootMode(const std::string &dbusMode)
525{
526 if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
527 {
528 return "None";
529 }
530 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe")
531 {
532 return "Diags";
533 }
534 else if (dbusMode == "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup")
535 {
536 return "BiosSetup";
537 }
538 else
539 {
540 return "";
541 }
542}
543
544/**
545 * @brief Traslates boot source from Redfish to DBUS property value.
546 *
547 * @param[in] rfSource The boot source in Redfish.
548 *
549 * @return Returns as a string, the boot source as expected by DBUS.
550 * If translation cannot be done, returns an empty string.
551 */
552static std::string rfToDbusBootSource(const std::string &rfSource)
553{
554 if (rfSource == "None")
555 {
556 return "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
557 }
558 else if (rfSource == "Hdd")
559 {
560 return "xyz.openbmc_project.Control.Boot.Source.Sources.Disk";
561 }
562 else if (rfSource == "Cd")
563 {
Santosh Puranika71dc0b2019-05-23 20:10:49 +0530564 return "xyz.openbmc_project.Control.Boot.Source.Sources.ExternalMedia";
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530565 }
566 else if (rfSource == "Pxe")
567 {
568 return "xyz.openbmc_project.Control.Boot.Source.Sources.Network";
569 }
Jennifer Lee9f16b2c2019-04-19 15:33:48 -0700570 else if (rfSource == "Usb")
571 {
572 return "xyz.openbmc_project.Control.Boot.Source.Sources.Removable";
573 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530574 else
575 {
576 return "";
577 }
578}
579
580/**
581 * @brief Traslates boot mode from Redfish to DBUS property value.
582 *
583 * @param[in] rfMode The boot mode in Redfish.
584 *
585 * @return Returns as a string, the boot mode as expected by DBUS.
586 * If translation cannot be done, returns an empty string.
587 */
588static std::string rfToDbusBootMode(const std::string &rfMode)
589{
590 if (rfMode == "None")
591 {
592 return "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
593 }
594 else if (rfMode == "Diags")
595 {
596 return "xyz.openbmc_project.Control.Boot.Mode.Modes.Safe";
597 }
598 else if (rfMode == "BiosSetup")
599 {
600 return "xyz.openbmc_project.Control.Boot.Mode.Modes.Setup";
601 }
602 else
603 {
604 return "";
605 }
606}
607
608/**
609 * @brief Retrieves boot mode over DBUS and fills out the response
610 *
611 * @param[in] aResp Shared pointer for generating response message.
612 * @param[in] bootDbusObj The dbus object to query for boot properties.
613 *
614 * @return None.
615 */
616static void getBootMode(std::shared_ptr<AsyncResp> aResp,
617 std::string bootDbusObj)
618{
619 crow::connections::systemBus->async_method_call(
620 [aResp](const boost::system::error_code ec,
621 const std::variant<std::string> &bootMode) {
622 if (ec)
623 {
624 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
625 messages::internalError(aResp->res);
626 return;
627 }
628
629 const std::string *bootModeStr =
630 std::get_if<std::string>(&bootMode);
631
632 if (!bootModeStr)
633 {
634 messages::internalError(aResp->res);
635 return;
636 }
637
638 BMCWEB_LOG_DEBUG << "Boot mode: " << *bootModeStr;
639
640 // TODO (Santosh): Do we need to support override mode?
641 aResp->res.jsonValue["Boot"]["BootSourceOverrideMode"] = "Legacy";
642 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget@Redfish."
643 "AllowableValues"] = {
644 "None", "Pxe", "Hdd", "Cd", "Diags", "BiosSetup"};
645
646 if (*bootModeStr !=
647 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
648 {
649 auto rfMode = dbusToRfBootMode(*bootModeStr);
650 if (!rfMode.empty())
651 {
652 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
653 rfMode;
654 }
655 }
656
657 // If the BootSourceOverrideTarget is still "None" at the end,
658 // reset the BootSourceOverrideEnabled to indicate that
659 // overrides are disabled
660 if (aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] ==
661 "None")
662 {
663 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
664 "Disabled";
665 }
666 },
667 "xyz.openbmc_project.Settings", bootDbusObj,
668 "org.freedesktop.DBus.Properties", "Get",
669 "xyz.openbmc_project.Control.Boot.Mode", "BootMode");
670}
671
672/**
673 * @brief Retrieves boot source over DBUS
674 *
675 * @param[in] aResp Shared pointer for generating response message.
676 * @param[in] oneTimeEnable Boolean to indicate boot properties are one-time.
677 *
678 * @return None.
679 */
680static void getBootSource(std::shared_ptr<AsyncResp> aResp, bool oneTimeEnabled)
681{
682 std::string bootDbusObj =
683 oneTimeEnabled ? "/xyz/openbmc_project/control/host0/boot/one_time"
684 : "/xyz/openbmc_project/control/host0/boot";
685
686 BMCWEB_LOG_DEBUG << "Is one time: " << oneTimeEnabled;
687 aResp->res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
688 (oneTimeEnabled) ? "Once" : "Continuous";
689
690 crow::connections::systemBus->async_method_call(
691 [aResp, bootDbusObj](const boost::system::error_code ec,
692 const std::variant<std::string> &bootSource) {
693 if (ec)
694 {
695 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
696 messages::internalError(aResp->res);
697 return;
698 }
699
700 const std::string *bootSourceStr =
701 std::get_if<std::string>(&bootSource);
702
703 if (!bootSourceStr)
704 {
705 messages::internalError(aResp->res);
706 return;
707 }
708 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSourceStr;
709
710 auto rfSource = dbusToRfBootSource(*bootSourceStr);
711 if (!rfSource.empty())
712 {
713 aResp->res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
714 rfSource;
715 }
716 },
717 "xyz.openbmc_project.Settings", bootDbusObj,
718 "org.freedesktop.DBus.Properties", "Get",
719 "xyz.openbmc_project.Control.Boot.Source", "BootSource");
720 getBootMode(std::move(aResp), std::move(bootDbusObj));
721}
722
723/**
724 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
725 * get boot source and boot mode.
726 *
727 * @param[in] aResp Shared pointer for generating response message.
728 *
729 * @return None.
730 */
731static void getBootProperties(std::shared_ptr<AsyncResp> aResp)
732{
733 BMCWEB_LOG_DEBUG << "Get boot information.";
734
735 crow::connections::systemBus->async_method_call(
Jennifer Leec5d03ff2019-03-08 15:42:58 -0800736 [aResp](const boost::system::error_code ec,
737 const sdbusplus::message::variant<bool> &oneTime) {
Santosh Puranik491d8ee2019-02-06 19:46:56 +0530738 if (ec)
739 {
740 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
741 messages::internalError(aResp->res);
742 return;
743 }
744
745 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
746
747 if (!oneTimePtr)
748 {
749 messages::internalError(aResp->res);
750 return;
751 }
752 getBootSource(aResp, *oneTimePtr);
753 },
754 "xyz.openbmc_project.Settings",
755 "/xyz/openbmc_project/control/host0/boot/one_time",
756 "org.freedesktop.DBus.Properties", "Get",
757 "xyz.openbmc_project.Object.Enable", "Enabled");
758}
759
760/**
761 * @brief Sets boot properties into DBUS object(s).
762 *
763 * @param[in] aResp Shared pointer for generating response message.
764 * @param[in] oneTimeEnabled Is "one-time" setting already enabled.
765 * @param[in] bootSource The boot source to set.
766 * @param[in] bootEnable The source override "enable" to set.
767 *
768 * @return None.
769 */
770static void setBootModeOrSource(std::shared_ptr<AsyncResp> aResp,
771 bool oneTimeEnabled,
772 std::optional<std::string> bootSource,
773 std::optional<std::string> bootEnable)
774{
775 if (bootEnable && (bootEnable != "Once") && (bootEnable != "Continuous") &&
776 (bootEnable != "Disabled"))
777 {
778 BMCWEB_LOG_DEBUG << "Unsupported value for BootSourceOverrideEnabled: "
779 << *bootEnable;
780 messages::propertyValueNotInList(aResp->res, *bootEnable,
781 "BootSourceOverrideEnabled");
782 return;
783 }
784
785 bool oneTimeSetting = oneTimeEnabled;
786 // Validate incoming parameters
787 if (bootEnable)
788 {
789 if (*bootEnable == "Once")
790 {
791 oneTimeSetting = true;
792 }
793 else if (*bootEnable == "Continuous")
794 {
795 oneTimeSetting = false;
796 }
797 else if (*bootEnable == "Disabled")
798 {
799 oneTimeSetting = false;
800 }
801 else
802 {
803
804 BMCWEB_LOG_DEBUG << "Unsupported value for "
805 "BootSourceOverrideEnabled: "
806 << *bootEnable;
807 messages::propertyValueNotInList(aResp->res, *bootEnable,
808 "BootSourceOverrideEnabled");
809 return;
810 }
811 }
812 std::string bootSourceStr;
813 std::string bootModeStr;
814 if (bootSource)
815 {
816 bootSourceStr = rfToDbusBootSource(*bootSource);
817 bootModeStr = rfToDbusBootMode(*bootSource);
818
819 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
820 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
821
822 if (bootSourceStr.empty() && bootModeStr.empty())
823 {
824 BMCWEB_LOG_DEBUG << "Invalid property value for "
825 "BootSourceOverrideTarget: "
826 << *bootSource;
827 messages::propertyValueNotInList(aResp->res, *bootSource,
828 "BootSourceTargetOverride");
829 return;
830 }
831 }
832 const char *bootObj =
833 oneTimeSetting ? "/xyz/openbmc_project/control/host0/boot/one_time"
834 : "/xyz/openbmc_project/control/host0/boot";
835 // Figure out what properties to set
836 if (bootEnable && (*bootEnable == "Disabled"))
837 {
838 BMCWEB_LOG_DEBUG << "Boot source override will be disabled";
839 // Request to only turn OFF/ON enabled, if turning enabled OFF, need
840 // to reset the source and mode too. If turning it ON, we only need
841 // to set the enabled property
842 bootSourceStr =
843 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
844 bootModeStr = "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
845 }
846 else if (bootSource)
847 {
848 // Source target specified
849 BMCWEB_LOG_DEBUG << "Boot source: " << *bootSource;
850 // Figure out which DBUS interface and property to use
851 bootSourceStr = rfToDbusBootSource(*bootSource);
852 bootModeStr = rfToDbusBootMode(*bootSource);
853
854 BMCWEB_LOG_DEBUG << "DBUS boot source: " << bootSourceStr;
855 BMCWEB_LOG_DEBUG << "DBUS boot mode: " << bootModeStr;
856
857 if (bootSourceStr.empty() && bootModeStr.empty())
858 {
859 BMCWEB_LOG_DEBUG << "Invalid property value for "
860 "BootSourceOverrideTarget: "
861 << *bootSource;
862 messages::propertyValueNotInList(aResp->res, *bootSource,
863 "BootSourceTargetOverride");
864 return;
865 }
866
867 if (!bootSourceStr.empty())
868 {
869 // If setting to anything other than default, also reset boot
870 // mode property
871 if (bootSourceStr !=
872 "xyz.openbmc_project.Control.Boot.Source.Sources.Default")
873 {
874 bootModeStr =
875 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular";
876 }
877 }
878 else // if (!bootModeStr.empty())
879 {
880 // If setting to anything other than default, also reset boot
881 // source property
882 if (bootModeStr !=
883 "xyz.openbmc_project.Control.Boot.Mode.Modes.Regular")
884 {
885 bootSourceStr =
886 "xyz.openbmc_project.Control.Boot.Source.Sources.Default";
887 }
888 }
889 }
890 if (!bootSourceStr.empty())
891 {
892 crow::connections::systemBus->async_method_call(
893 [aResp](const boost::system::error_code ec) {
894 if (ec)
895 {
896 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
897 messages::internalError(aResp->res);
898 return;
899 }
900 BMCWEB_LOG_DEBUG << "Boot source update done.";
901 },
902 "xyz.openbmc_project.Settings", bootObj,
903 "org.freedesktop.DBus.Properties", "Set",
904 "xyz.openbmc_project.Control.Boot.Source", "BootSource",
905 std::variant<std::string>(bootSourceStr));
906 }
907 if (!bootModeStr.empty())
908 {
909 crow::connections::systemBus->async_method_call(
910 [aResp](const boost::system::error_code ec) {
911 if (ec)
912 {
913 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
914 messages::internalError(aResp->res);
915 return;
916 }
917 BMCWEB_LOG_DEBUG << "Boot mode update done.";
918 },
919 "xyz.openbmc_project.Settings", bootObj,
920 "org.freedesktop.DBus.Properties", "Set",
921 "xyz.openbmc_project.Control.Boot.Mode", "BootMode",
922 std::variant<std::string>(bootModeStr));
923 }
924 crow::connections::systemBus->async_method_call(
925 [aResp{std::move(aResp)}](const boost::system::error_code ec) {
926 if (ec)
927 {
928 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
929 messages::internalError(aResp->res);
930 return;
931 }
932 BMCWEB_LOG_DEBUG << "Boot enable update done.";
933 },
934 "xyz.openbmc_project.Settings",
935 "/xyz/openbmc_project/control/host0/boot/one_time",
936 "org.freedesktop.DBus.Properties", "Set",
937 "xyz.openbmc_project.Object.Enable", "Enabled",
938 std::variant<bool>(oneTimeSetting));
939}
940
941/**
942 * @brief Retrieves "One time" enabled setting over DBUS and calls function to
943 * set boot source/boot mode properties.
944 *
945 * @param[in] aResp Shared pointer for generating response message.
946 * @param[in] bootSource The boot source from incoming RF request.
947 * @param[in] bootEnable The boot override enable from incoming RF request.
948 *
949 * @return None.
950 */
951static void setBootProperties(std::shared_ptr<AsyncResp> aResp,
952 std::optional<std::string> bootSource,
953 std::optional<std::string> bootEnable)
954{
955 BMCWEB_LOG_DEBUG << "Set boot information.";
956
957 crow::connections::systemBus->async_method_call(
958 [aResp{std::move(aResp)}, bootSource{std::move(bootSource)},
959 bootEnable{std::move(bootEnable)}](
960 const boost::system::error_code ec,
961 const sdbusplus::message::variant<bool> &oneTime) {
962 if (ec)
963 {
964 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
965 messages::internalError(aResp->res);
966 return;
967 }
968
969 const bool *oneTimePtr = std::get_if<bool>(&oneTime);
970
971 if (!oneTimePtr)
972 {
973 messages::internalError(aResp->res);
974 return;
975 }
976
977 BMCWEB_LOG_DEBUG << "Got one time: " << *oneTimePtr;
978
979 setBootModeOrSource(aResp, *oneTimePtr, std::move(bootSource),
980 std::move(bootEnable));
981 },
982 "xyz.openbmc_project.Settings",
983 "/xyz/openbmc_project/control/host0/boot/one_time",
984 "org.freedesktop.DBus.Properties", "Get",
985 "xyz.openbmc_project.Object.Enable", "Enabled");
986}
987
988/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200989 * SystemsCollection derived class for delivering ComputerSystems Collection
990 * Schema
991 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700992class SystemsCollection : public Node
993{
994 public:
995 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
996 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700997 entityPrivileges = {
998 {boost::beast::http::verb::get, {{"Login"}}},
999 {boost::beast::http::verb::head, {{"Login"}}},
1000 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1001 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1002 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1003 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1004 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001005
Ed Tanous1abe55e2018-09-05 08:30:59 -07001006 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001007 void doGet(crow::Response &res, const crow::Request &req,
1008 const std::vector<std::string> &params) override
1009 {
Ed Tanous0f74e642018-11-12 15:17:05 -08001010 res.jsonValue["@odata.type"] =
1011 "#ComputerSystemCollection.ComputerSystemCollection";
1012 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
1013 res.jsonValue["@odata.context"] =
1014 "/redfish/v1/"
1015 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
1016 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -08001017 res.jsonValue["Members"] = {
1018 {{"@odata.id", "/redfish/v1/Systems/system"}}};
1019 res.jsonValue["Members@odata.count"] = 1;
1020 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -07001021 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001022};
1023
1024/**
Ed Tanouscc340dd2018-08-29 13:43:38 -07001025 * SystemActionsReset class supports handle POST method for Reset action.
1026 * The class retrieves and sends data directly to D-Bus.
1027 */
1028class SystemActionsReset : public Node
1029{
1030 public:
1031 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -08001032 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -07001033 {
1034 entityPrivileges = {
1035 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
1036 }
1037
1038 private:
1039 /**
1040 * Function handles POST method request.
1041 * Analyzes POST body message before sends Reset request data to D-Bus.
1042 */
1043 void doPost(crow::Response &res, const crow::Request &req,
1044 const std::vector<std::string> &params) override
1045 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001046 auto asyncResp = std::make_shared<AsyncResp>(res);
1047
1048 std::string resetType;
1049 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -07001050 {
1051 return;
1052 }
1053
Jason M. Billsd22c8392019-06-03 13:59:03 -07001054 // Get the command and host vs. chassis
Ed Tanous9712f8a2018-09-21 13:38:49 -07001055 std::string command;
Jason M. Billsd22c8392019-06-03 13:59:03 -07001056 bool hostCommand;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001057 if (resetType == "On")
1058 {
1059 command = "xyz.openbmc_project.State.Host.Transition.On";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001060 hostCommand = true;
1061 }
1062 else if (resetType == "ForceOff")
1063 {
1064 command = "xyz.openbmc_project.State.Chassis.Transition.Off";
1065 hostCommand = false;
1066 }
1067 else if (resetType == "ForceOn")
1068 {
1069 command = "xyz.openbmc_project.State.Host.Transition.On";
1070 hostCommand = true;
1071 }
1072 else if (resetType == "ForceRestart")
1073 {
1074 command = "xyz.openbmc_project.State.Chassis.Transition.Reset";
1075 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001076 }
1077 else if (resetType == "GracefulShutdown")
1078 {
1079 command = "xyz.openbmc_project.State.Host.Transition.Off";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001080 hostCommand = true;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001081 }
1082 else if (resetType == "GracefulRestart")
1083 {
1084 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
Jason M. Billsd22c8392019-06-03 13:59:03 -07001085 hostCommand = true;
1086 }
1087 else if (resetType == "PowerCycle")
1088 {
1089 command = "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
1090 hostCommand = false;
Ed Tanous9712f8a2018-09-21 13:38:49 -07001091 }
1092 else
1093 {
Jason M. Billsf12894f2018-10-09 12:45:45 -07001094 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001095 return;
1096 }
1097
Jason M. Billsd22c8392019-06-03 13:59:03 -07001098 if (hostCommand)
1099 {
1100 crow::connections::systemBus->async_method_call(
1101 [asyncResp, resetType](const boost::system::error_code ec) {
1102 if (ec)
1103 {
1104 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1105 if (ec.value() == boost::asio::error::invalid_argument)
1106 {
1107 messages::actionParameterNotSupported(
1108 asyncResp->res, resetType, "Reset");
1109 }
1110 else
1111 {
1112 messages::internalError(asyncResp->res);
1113 }
1114 return;
1115 }
1116 messages::success(asyncResp->res);
1117 },
1118 "xyz.openbmc_project.State.Host",
1119 "/xyz/openbmc_project/state/host0",
1120 "org.freedesktop.DBus.Properties", "Set",
1121 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
1122 std::variant<std::string>{command});
1123 }
1124 else
1125 {
1126 crow::connections::systemBus->async_method_call(
1127 [asyncResp, resetType](const boost::system::error_code ec) {
1128 if (ec)
1129 {
1130 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
1131 if (ec.value() == boost::asio::error::invalid_argument)
1132 {
1133 messages::actionParameterNotSupported(
1134 asyncResp->res, resetType, "Reset");
1135 }
1136 else
1137 {
1138 messages::internalError(asyncResp->res);
1139 }
1140 return;
1141 }
1142 messages::success(asyncResp->res);
1143 },
1144 "xyz.openbmc_project.State.Chassis",
1145 "/xyz/openbmc_project/state/chassis0",
1146 "org.freedesktop.DBus.Properties", "Set",
1147 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
1148 std::variant<std::string>{command});
1149 }
Ed Tanouscc340dd2018-08-29 13:43:38 -07001150 }
1151};
1152
1153/**
Ed Tanous66173382018-08-15 18:20:59 -07001154 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001155 */
Ed Tanous1abe55e2018-09-05 08:30:59 -07001156class Systems : public Node
1157{
1158 public:
1159 /*
1160 * Default Constructor
1161 */
Ed Tanous029573d2019-02-01 10:57:49 -08001162 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -07001163 {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001164 entityPrivileges = {
1165 {boost::beast::http::verb::get, {{"Login"}}},
1166 {boost::beast::http::verb::head, {{"Login"}}},
1167 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
1168 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
1169 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
1170 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001171 }
1172
Ed Tanous1abe55e2018-09-05 08:30:59 -07001173 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -07001174 /**
1175 * Functions triggers appropriate requests on DBus
1176 */
1177 void doGet(crow::Response &res, const crow::Request &req,
1178 const std::vector<std::string> &params) override
1179 {
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301180 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_6_0.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -08001181 res.jsonValue["@odata.context"] =
1182 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -08001183 res.jsonValue["Name"] = "Computer System";
1184 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -08001185 res.jsonValue["SystemType"] = "Physical";
1186 res.jsonValue["Description"] = "Computer System";
Ed Tanous0f74e642018-11-12 15:17:05 -08001187 res.jsonValue["ProcessorSummary"]["Count"] = 0;
1188 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
1189 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
1190 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -08001191 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -07001192
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001193 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001194 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +02001195 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001196 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
1197
Ed Tanouscc340dd2018-08-29 13:43:38 -07001198 // TODO Need to support ForceRestart.
1199 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
1200 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -08001201 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -07001202 {"ResetType@Redfish.AllowableValues",
Jason M. Billsd22c8392019-06-03 13:59:03 -07001203 {"On", "ForceOff", "ForceOn", "ForceRestart", "GracefulRestart",
1204 "GracefulShutdown", "PowerCycle"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001205
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001206 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -08001207 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -08001208
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001209 res.jsonValue["Links"]["ManagedBy"] = {
1210 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
1211
1212 res.jsonValue["Status"] = {
1213 {"Health", "OK"},
1214 {"State", "Enabled"},
1215 };
Ed Tanousa0803ef2018-08-29 13:29:23 -07001216 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -07001217
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001218 getMainChassisId(asyncResp, [](const std::string &chassisId,
1219 std::shared_ptr<AsyncResp> aRsp) {
1220 aRsp->res.jsonValue["Links"]["Chassis"] = {
1221 {{"@odata.id", "/redfish/v1/Chassis/" + chassisId}}};
1222 });
Ed Tanous6c34de42018-08-29 13:37:36 -07001223 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -07001224 asyncResp,
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001225 [](const bool &asserted, const std::shared_ptr<AsyncResp> aRsp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001226 if (asserted)
1227 {
1228 // If led group is asserted, then another call is needed to
1229 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -07001230 getLedIdentify(
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001231 aRsp, [](const std::string &ledStatus,
1232 const std::shared_ptr<AsyncResp> aRsp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -07001233 if (!ledStatus.empty())
1234 {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001235 aRsp->res.jsonValue["IndicatorLED"] = ledStatus;
Ed Tanous1abe55e2018-09-05 08:30:59 -07001236 }
1237 });
1238 }
1239 else
1240 {
Jennifer Leec5d03ff2019-03-08 15:42:58 -08001241 aRsp->res.jsonValue["IndicatorLED"] = "Off";
Ed Tanous1abe55e2018-09-05 08:30:59 -07001242 }
1243 });
Ed Tanous029573d2019-02-01 10:57:49 -08001244 getComputerSystem(asyncResp);
Ed Tanous6c34de42018-08-29 13:37:36 -07001245 getHostState(asyncResp);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301246 getBootProperties(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001247 }
1248
Ed Tanous1abe55e2018-09-05 08:30:59 -07001249 void doPatch(crow::Response &res, const crow::Request &req,
1250 const std::vector<std::string> &params) override
1251 {
Santosh Puranikcde19e52019-02-20 00:10:56 +05301252 std::optional<std::string> indicatorLed;
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301253 std::optional<nlohmann::json> bootProps;
1254 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
1255 bootProps))
Ed Tanous66173382018-08-15 18:20:59 -07001256 {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001257 return;
1258 }
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301259
Ed Tanous029573d2019-02-01 10:57:49 -08001260 auto asyncResp = std::make_shared<AsyncResp>(res);
Jennifer Leed573bb22019-04-10 13:49:51 -07001261 asyncResp->res.result(boost::beast::http::status::no_content);
Santosh Puranik491d8ee2019-02-06 19:46:56 +05301262
1263 if (bootProps)
1264 {
1265 std::optional<std::string> bootSource;
1266 std::optional<std::string> bootEnable;
1267
1268 if (!json_util::readJson(*bootProps, asyncResp->res,
1269 "BootSourceOverrideTarget", bootSource,
1270 "BootSourceOverrideEnabled", bootEnable))
1271 {
1272 return;
1273 }
1274 setBootProperties(asyncResp, std::move(bootSource),
1275 std::move(bootEnable));
1276 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001277 if (indicatorLed)
1278 {
1279 std::string dbusLedState;
Jennifer Leed573bb22019-04-10 13:49:51 -07001280 if (*indicatorLed == "Lit")
Ed Tanous66173382018-08-15 18:20:59 -07001281 {
Jennifer Leed573bb22019-04-10 13:49:51 -07001282 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.On";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001283 }
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001284 else if (*indicatorLed == "Blinking")
Ed Tanous9712f8a2018-09-21 13:38:49 -07001285 {
Gunnar Mills5c6221a2019-02-22 11:24:29 -06001286 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Blink";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001287 }
1288 else if (*indicatorLed == "Off")
1289 {
1290 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -07001291 }
1292 else
1293 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -08001294 messages::propertyValueNotInList(res, *indicatorLed,
1295 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -07001296 return;
1297 }
Ed Tanous9712f8a2018-09-21 13:38:49 -07001298
Ed Tanous9712f8a2018-09-21 13:38:49 -07001299 // Update led group
1300 BMCWEB_LOG_DEBUG << "Update led group.";
1301 crow::connections::systemBus->async_method_call(
Santosh Puranikcde19e52019-02-20 00:10:56 +05301302 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -07001303 if (ec)
1304 {
1305 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001306 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001307 return;
1308 }
1309 BMCWEB_LOG_DEBUG << "Led group update done.";
1310 },
1311 "xyz.openbmc_project.LED.GroupManager",
1312 "/xyz/openbmc_project/led/groups/enclosure_identify",
1313 "org.freedesktop.DBus.Properties", "Set",
1314 "xyz.openbmc_project.Led.Group", "Asserted",
Ed Tanousabf2add2019-01-22 16:40:12 -08001315 std::variant<bool>(
Ed Tanous9712f8a2018-09-21 13:38:49 -07001316 (dbusLedState ==
1317 "xyz.openbmc_project.Led.Physical.Action.Off"
1318 ? false
1319 : true)));
1320 // Update identify led status
1321 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
1322 crow::connections::systemBus->async_method_call(
1323 [asyncResp{std::move(asyncResp)},
1324 indicatorLed{std::move(*indicatorLed)}](
1325 const boost::system::error_code ec) {
1326 if (ec)
1327 {
1328 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -07001329 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -07001330 return;
1331 }
1332 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -07001333 },
1334 "xyz.openbmc_project.LED.Controller.identify",
1335 "/xyz/openbmc_project/led/physical/identify",
1336 "org.freedesktop.DBus.Properties", "Set",
1337 "xyz.openbmc_project.Led.Physical", "State",
Ed Tanousabf2add2019-01-22 16:40:12 -08001338 std::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -07001339 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001340 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +02001341};
Ed Tanous1abe55e2018-09-05 08:30:59 -07001342} // namespace redfish