blob: 5e8b9a50f22493489e46e982ab7a4c0c3a1b4f82 [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 *
306 * @param[in] aResp Shared pointer for completing asynchronous calls.
307 * @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/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200460 * SystemsCollection derived class for delivering ComputerSystems Collection
461 * Schema
462 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700463class SystemsCollection : public Node
464{
465 public:
466 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
467 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700468 entityPrivileges = {
469 {boost::beast::http::verb::get, {{"Login"}}},
470 {boost::beast::http::verb::head, {{"Login"}}},
471 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
472 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
473 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
474 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
475 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200476
Ed Tanous1abe55e2018-09-05 08:30:59 -0700477 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700478 void doGet(crow::Response &res, const crow::Request &req,
479 const std::vector<std::string> &params) override
480 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800481 res.jsonValue["@odata.type"] =
482 "#ComputerSystemCollection.ComputerSystemCollection";
483 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
484 res.jsonValue["@odata.context"] =
485 "/redfish/v1/"
486 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
487 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -0800488 res.jsonValue["Members"] = {
489 {{"@odata.id", "/redfish/v1/Systems/system"}}};
490 res.jsonValue["Members@odata.count"] = 1;
491 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -0700492 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200493};
494
495/**
Ed Tanouscc340dd2018-08-29 13:43:38 -0700496 * SystemActionsReset class supports handle POST method for Reset action.
497 * The class retrieves and sends data directly to D-Bus.
498 */
499class SystemActionsReset : public Node
500{
501 public:
502 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800503 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700504 {
505 entityPrivileges = {
506 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
507 }
508
509 private:
510 /**
511 * Function handles POST method request.
512 * Analyzes POST body message before sends Reset request data to D-Bus.
513 */
514 void doPost(crow::Response &res, const crow::Request &req,
515 const std::vector<std::string> &params) override
516 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700517 auto asyncResp = std::make_shared<AsyncResp>(res);
518
519 std::string resetType;
520 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -0700521 {
522 return;
523 }
524
Ed Tanous9712f8a2018-09-21 13:38:49 -0700525 if (resetType == "ForceOff")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700526 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700527 // Force off acts on the chassis
528 crow::connections::systemBus->async_method_call(
529 [asyncResp](const boost::system::error_code ec) {
530 if (ec)
531 {
532 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700533 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700534 return;
535 }
536 // TODO Consider support polling mechanism to verify
537 // status of host and chassis after execute the
538 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700539 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700540 },
541 "xyz.openbmc_project.State.Chassis",
542 "/xyz/openbmc_project/state/chassis0",
543 "org.freedesktop.DBus.Properties", "Set",
544 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
Ed Tanousabf2add2019-01-22 16:40:12 -0800545 std::variant<std::string>{
Ed Tanous9712f8a2018-09-21 13:38:49 -0700546 "xyz.openbmc_project.State.Chassis.Transition.Off"});
547 return;
Ed Tanouscc340dd2018-08-29 13:43:38 -0700548 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700549 // all other actions operate on the host
550 std::string command;
551 // Execute Reset Action regarding to each reset type.
552 if (resetType == "On")
553 {
554 command = "xyz.openbmc_project.State.Host.Transition.On";
555 }
556 else if (resetType == "GracefulShutdown")
557 {
558 command = "xyz.openbmc_project.State.Host.Transition.Off";
559 }
560 else if (resetType == "GracefulRestart")
561 {
562 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
563 }
564 else
565 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700566 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700567 return;
568 }
569
570 crow::connections::systemBus->async_method_call(
571 [asyncResp](const boost::system::error_code ec) {
572 if (ec)
573 {
574 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700575 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700576 return;
577 }
578 // TODO Consider support polling mechanism to verify
579 // status of host and chassis after execute the
580 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700581 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700582 },
583 "xyz.openbmc_project.State.Host",
584 "/xyz/openbmc_project/state/host0",
585 "org.freedesktop.DBus.Properties", "Set",
586 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
Ed Tanousabf2add2019-01-22 16:40:12 -0800587 std::variant<std::string>{command});
Ed Tanouscc340dd2018-08-29 13:43:38 -0700588 }
589};
590
591/**
Ed Tanous66173382018-08-15 18:20:59 -0700592 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200593 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700594class Systems : public Node
595{
596 public:
597 /*
598 * Default Constructor
599 */
Ed Tanous029573d2019-02-01 10:57:49 -0800600 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -0700601 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700602 entityPrivileges = {
603 {boost::beast::http::verb::get, {{"Login"}}},
604 {boost::beast::http::verb::head, {{"Login"}}},
605 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
606 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
607 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
608 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200609 }
610
Ed Tanous1abe55e2018-09-05 08:30:59 -0700611 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700612 /**
613 * Functions triggers appropriate requests on DBus
614 */
615 void doGet(crow::Response &res, const crow::Request &req,
616 const std::vector<std::string> &params) override
617 {
Rapkiewicz, Pawelbb3d9942018-11-22 10:59:11 +0100618 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_5_1.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -0800619 res.jsonValue["@odata.context"] =
620 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -0800621 res.jsonValue["Name"] = "Computer System";
622 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -0800623 res.jsonValue["SystemType"] = "Physical";
624 res.jsonValue["Description"] = "Computer System";
625 res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
626 "Disabled"; // TODO(Dawid), get real boot data
627 res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
628 "None"; // TODO(Dawid), get real boot data
629 res.jsonValue["Boot"]["BootSourceOverrideMode"] =
630 "Legacy"; // TODO(Dawid), get real boot data
631 res.jsonValue["Boot"]
632 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
633 "None", "Pxe", "Hdd", "Cd",
634 "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
635 // data
636 res.jsonValue["ProcessorSummary"]["Count"] = 0;
637 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
638 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
639 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -0800640 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -0700641
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200642 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800643 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200644 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800645 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
646
Ed Tanouscc340dd2018-08-29 13:43:38 -0700647 // TODO Need to support ForceRestart.
648 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
649 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -0800650 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -0700651 {"ResetType@Redfish.AllowableValues",
652 {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200653
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800654 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800655 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800656
Ed Tanousa0803ef2018-08-29 13:29:23 -0700657 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700658
Ed Tanous6c34de42018-08-29 13:37:36 -0700659 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700660 asyncResp,
661 [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700662 if (asserted)
663 {
664 // If led group is asserted, then another call is needed to
665 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -0700666 getLedIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700667 aResp, [](const std::string &ledStatus,
668 const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700669 if (!ledStatus.empty())
670 {
671 aResp->res.jsonValue["IndicatorLED"] =
672 ledStatus;
673 }
674 });
675 }
676 else
677 {
678 aResp->res.jsonValue["IndicatorLED"] = "Off";
679 }
680 });
Ed Tanous029573d2019-02-01 10:57:49 -0800681 getComputerSystem(asyncResp);
Ed Tanous6c34de42018-08-29 13:37:36 -0700682 getHostState(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200683 }
684
Ed Tanous1abe55e2018-09-05 08:30:59 -0700685 void doPatch(crow::Response &res, const crow::Request &req,
686 const std::vector<std::string> &params) override
687 {
Santosh Puranikcde19e52019-02-20 00:10:56 +0530688 std::optional<std::string> indicatorLed;
689 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed))
Ed Tanous66173382018-08-15 18:20:59 -0700690 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700691 return;
692 }
Ed Tanous029573d2019-02-01 10:57:49 -0800693 auto asyncResp = std::make_shared<AsyncResp>(res);
694 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700695 if (indicatorLed)
696 {
697 std::string dbusLedState;
698 if (*indicatorLed == "On")
Ed Tanous66173382018-08-15 18:20:59 -0700699 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700700 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
701 }
702 else if (*indicatorLed == "Blink")
703 {
704 dbusLedState =
705 "xyz.openbmc_project.Led.Physical.Action.Blinking";
706 }
707 else if (*indicatorLed == "Off")
708 {
709 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -0700710 }
711 else
712 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -0800713 messages::propertyValueNotInList(res, *indicatorLed,
714 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -0700715 return;
716 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700717
718 getHostState(asyncResp);
Ed Tanous029573d2019-02-01 10:57:49 -0800719 getComputerSystem(asyncResp);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700720
721 // Update led group
722 BMCWEB_LOG_DEBUG << "Update led group.";
723 crow::connections::systemBus->async_method_call(
Santosh Puranikcde19e52019-02-20 00:10:56 +0530724 [asyncResp](const boost::system::error_code ec) {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700725 if (ec)
726 {
727 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700728 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700729 return;
730 }
731 BMCWEB_LOG_DEBUG << "Led group update done.";
732 },
733 "xyz.openbmc_project.LED.GroupManager",
734 "/xyz/openbmc_project/led/groups/enclosure_identify",
735 "org.freedesktop.DBus.Properties", "Set",
736 "xyz.openbmc_project.Led.Group", "Asserted",
Ed Tanousabf2add2019-01-22 16:40:12 -0800737 std::variant<bool>(
Ed Tanous9712f8a2018-09-21 13:38:49 -0700738 (dbusLedState ==
739 "xyz.openbmc_project.Led.Physical.Action.Off"
740 ? false
741 : true)));
742 // Update identify led status
743 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
744 crow::connections::systemBus->async_method_call(
745 [asyncResp{std::move(asyncResp)},
746 indicatorLed{std::move(*indicatorLed)}](
747 const boost::system::error_code ec) {
748 if (ec)
749 {
750 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700751 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700752 return;
753 }
754 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -0700755 },
756 "xyz.openbmc_project.LED.Controller.identify",
757 "/xyz/openbmc_project/led/physical/identify",
758 "org.freedesktop.DBus.Properties", "Set",
759 "xyz.openbmc_project.Led.Physical", "State",
Ed Tanousabf2add2019-01-22 16:40:12 -0800760 std::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -0700761 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200762 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200763};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700764} // namespace redfish