blob: 7097cfcac6731308c61942e687c25ab8de88207e [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>
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020021
Ed Tanous1abe55e2018-09-05 08:30:59 -070022namespace redfish
23{
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020024
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +020025/**
Ed Tanous6c34de42018-08-29 13:37:36 -070026 * @brief Retrieves computer system properties over dbus
27 *
28 * @param[in] aResp Shared pointer for completing asynchronous calls
29 * @param[in] name Computer system name from request
30 *
31 * @return None.
32 */
33void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
34 const std::string &name)
35{
Ed Tanous6c34de42018-08-29 13:37:36 -070036 BMCWEB_LOG_DEBUG << "Get available system components.";
37 crow::connections::systemBus->async_method_call(
38 [name, aResp{std::move(aResp)}](
39 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";
47 aResp->res.result(
48 boost::beast::http::status::internal_server_error);
49 return;
50 }
51 bool foundName = false;
52 // Iterate over all retrieved ObjectPaths.
53 for (const std::pair<std::string,
54 std::vector<std::pair<
55 std::string, std::vector<std::string>>>>
56 &object : subtree)
57 {
58 const std::string &path = object.first;
59 BMCWEB_LOG_DEBUG << "Got path: " << path;
60 const std::vector<
61 std::pair<std::string, std::vector<std::string>>>
62 &connectionNames = object.second;
63 if (connectionNames.size() < 1)
64 {
65 continue;
66 }
67 // Check if computer system exist
68 if (boost::ends_with(path, name))
69 {
70 foundName = true;
71 BMCWEB_LOG_DEBUG << "Found name: " << name;
72 const std::string connectionName = connectionNames[0].first;
73 crow::connections::systemBus->async_method_call(
74 [aResp, name(std::string(name))](
75 const boost::system::error_code ec,
76 const std::vector<std::pair<
77 std::string, VariantType>> &propertiesList) {
78 if (ec)
79 {
80 BMCWEB_LOG_ERROR << "DBUS response error: "
81 << ec;
82 aResp->res.result(boost::beast::http::status::
83 internal_server_error);
84 return;
85 }
86 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
87 << "properties for system";
88 for (const std::pair<std::string, VariantType>
89 &property : propertiesList)
90 {
91 const std::string *value =
92 mapbox::getPtr<const std::string>(
93 property.second);
94 if (value != nullptr)
95 {
96 aResp->res.jsonValue[property.first] =
97 *value;
98 }
99 }
100 aResp->res.jsonValue["Name"] = name;
101 aResp->res.jsonValue["Id"] =
102 aResp->res.jsonValue["SerialNumber"];
103 },
104 connectionName, path, "org.freedesktop.DBus.Properties",
105 "GetAll",
106 "xyz.openbmc_project.Inventory.Decorator.Asset");
107 }
108 else
109 {
110 // This is not system, so check if it's cpu, dimm, UUID or
111 // BiosVer
Ed Tanous04a258f2018-10-15 08:00:41 -0700112 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700113 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700114 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700115 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700116 if (interfaceName ==
117 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700118 {
119 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700120 << "Found Dimm, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700121 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700122 [aResp](
Ed Tanous6c34de42018-08-29 13:37:36 -0700123 const boost::system::error_code ec,
124 const std::vector<
125 std::pair<std::string, VariantType>>
126 &properties) {
127 if (ec)
128 {
129 BMCWEB_LOG_ERROR
130 << "DBUS response error " << ec;
131 aResp->res.result(
132 boost::beast::http::status::
133 internal_server_error);
134 return;
135 }
136 BMCWEB_LOG_DEBUG << "Got "
137 << properties.size()
138 << "Dimm properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700139 for (const std::pair<std::string,
140 VariantType>
141 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700142 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700143 if (property.first ==
144 "MemorySizeInKb")
Ed Tanous6c34de42018-08-29 13:37:36 -0700145 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700146 const uint64_t *value =
Ed Tanous6c34de42018-08-29 13:37:36 -0700147 mapbox::getPtr<
Ed Tanous04a258f2018-10-15 08:00:41 -0700148 const uint64_t>(
149 property.second);
150 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700151 {
Ed Tanous6c34de42018-08-29 13:37:36 -0700152 aResp->res.jsonValue
153 ["TotalSystemMemoryGi"
154 "B"] +=
Ed Tanous04a258f2018-10-15 08:00:41 -0700155 *value / (1024 * 1024);
Ed Tanous6c34de42018-08-29 13:37:36 -0700156 aResp->res.jsonValue
157 ["MemorySummary"]
158 ["Status"]["State"] =
159 "Enabled";
160 }
161 }
162 }
163 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700164 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700165 "org.freedesktop.DBus.Properties", "GetAll",
166 "xyz.openbmc_project.Inventory.Item.Dimm");
167 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700168 else if (interfaceName ==
169 "xyz.openbmc_project.Inventory.Item.Cpu")
Ed Tanous6c34de42018-08-29 13:37:36 -0700170 {
171 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700172 << "Found Cpu, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700173 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700174 [aResp](
Ed Tanous6c34de42018-08-29 13:37:36 -0700175 const boost::system::error_code ec,
176 const std::vector<
177 std::pair<std::string, VariantType>>
178 &properties) {
179 if (ec)
180 {
181 BMCWEB_LOG_ERROR
182 << "DBUS response error " << ec;
183 aResp->res.result(
184 boost::beast::http::status::
185 internal_server_error);
186 return;
187 }
188 BMCWEB_LOG_DEBUG << "Got "
189 << properties.size()
190 << "Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700191 for (const auto &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700192 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700193 if (property.first ==
194 "ProcessorFamily")
Ed Tanous6c34de42018-08-29 13:37:36 -0700195 {
196 const std::string *value =
197 mapbox::getPtr<
198 const std::string>(
Ed Tanous04a258f2018-10-15 08:00:41 -0700199 property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700200 if (value != nullptr)
201 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700202 nlohmann::json
203 &procSummary =
204 aResp->res.jsonValue
Ed Tanous6c34de42018-08-29 13:37:36 -0700205 ["ProcessorSumm"
Ed Tanous04a258f2018-10-15 08:00:41 -0700206 "ary"];
207 nlohmann::json &procCount =
208 procSummary["Count"];
209
210 procCount =
211 procCount.get<int>() +
Ed Tanous6c34de42018-08-29 13:37:36 -0700212 1;
Ed Tanous04a258f2018-10-15 08:00:41 -0700213 procSummary["Status"]
214 ["State"] =
215 "Enabled";
216 procSummary["Model"] =
217 *value;
Ed Tanous6c34de42018-08-29 13:37:36 -0700218 }
219 }
220 }
221 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700222 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700223 "org.freedesktop.DBus.Properties", "GetAll",
224 "xyz.openbmc_project.Inventory.Item.Cpu");
225 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700226 else if (interfaceName ==
227 "xyz.openbmc_project.Common.UUID")
Ed Tanous6c34de42018-08-29 13:37:36 -0700228 {
229 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700230 << "Found UUID, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700231 crow::connections::systemBus->async_method_call(
232 [aResp](
233 const boost::system::error_code ec,
234 const std::vector<
235 std::pair<std::string, VariantType>>
236 &properties) {
237 if (ec)
238 {
239 BMCWEB_LOG_DEBUG
240 << "DBUS response error " << ec;
241 aResp->res.result(
242 boost::beast::http::status::
243 internal_server_error);
244 return;
245 }
246 BMCWEB_LOG_DEBUG << "Got "
247 << properties.size()
248 << "UUID properties.";
249 for (const std::pair<std::string,
Ed Tanous04a258f2018-10-15 08:00:41 -0700250 VariantType>
251 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700252 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700253 if (property.first == "BIOSVer")
Ed Tanous6c34de42018-08-29 13:37:36 -0700254 {
255 const std::string *value =
256 mapbox::getPtr<
257 const std::string>(
Ed Tanous04a258f2018-10-15 08:00:41 -0700258 property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700259 if (value != nullptr)
260 {
261 aResp->res.jsonValue
262 ["BiosVersion"] =
263 *value;
264 }
265 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700266 if (property.first == "UUID")
Ed Tanous6c34de42018-08-29 13:37:36 -0700267 {
268 const std::string *value =
269 mapbox::getPtr<
270 const std::string>(
Ed Tanous04a258f2018-10-15 08:00:41 -0700271 property.second);
272
Ed Tanous6c34de42018-08-29 13:37:36 -0700273 if (value != nullptr)
274 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700275 std::string valueStr =
276 *value;
277 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700278 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700279 valueStr.insert(8, 1,
280 '-');
281 valueStr.insert(13, 1,
282 '-');
283 valueStr.insert(18, 1,
284 '-');
285 valueStr.insert(23, 1,
286 '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700287 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700288 BMCWEB_LOG_DEBUG
289 << "UUID = "
290 << valueStr;
291 aResp->res
292 .jsonValue["UUID"] =
293 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700294 }
295 }
296 }
297 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700298 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700299 "org.freedesktop.DBus.Properties", "GetAll",
300 "xyz.openbmc_project.Common.UUID");
301 }
302 }
303 }
304 }
305 }
306 if (foundName == false)
307 {
308 aResp->res.result(
309 boost::beast::http::status::internal_server_error);
310 }
311 },
312 "xyz.openbmc_project.ObjectMapper",
313 "/xyz/openbmc_project/object_mapper",
314 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700315 "/xyz/openbmc_project/inventory", int32_t(0),
316 std::array<const char *, 5>{
317 "xyz.openbmc_project.Inventory.Decorator.Asset",
318 "xyz.openbmc_project.Inventory.Item.Cpu",
319 "xyz.openbmc_project.Inventory.Item.Dimm",
320 "xyz.openbmc_project.Inventory.Item.System",
321 "xyz.openbmc_project.Common.UUID",
322 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700323}
324
325/**
326 * @brief Retrieves identify led group properties over dbus
327 *
328 * @param[in] aResp Shared pointer for completing asynchronous calls.
329 * @param[in] callback Callback for process retrieved data.
330 *
331 * @return None.
332 */
333template <typename CallbackFunc>
334void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
335 CallbackFunc &&callback)
336{
337 BMCWEB_LOG_DEBUG << "Get led groups";
338 crow::connections::systemBus->async_method_call(
339 [aResp{std::move(aResp)},
Ed Tanous66173382018-08-15 18:20:59 -0700340 callback{std::move(callback)}](const boost::system::error_code &ec,
341 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700342 if (ec)
343 {
344 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
345 aResp->res.result(
346 boost::beast::http::status::internal_server_error);
347 return;
348 }
349 BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
350 for (const auto &objPath : resp)
351 {
352 const std::string &path = objPath.first;
353 if (path.rfind("enclosure_identify") != std::string::npos)
354 {
355 for (const auto &interface : objPath.second)
356 {
357 if (interface.first == "xyz.openbmc_project.Led.Group")
358 {
359 for (const auto &property : interface.second)
360 {
361 if (property.first == "Asserted")
362 {
363 const bool *asserted =
364 mapbox::getPtr<const bool>(
365 property.second);
366 if (nullptr != asserted)
367 {
368 callback(*asserted, aResp);
369 }
370 else
371 {
372 callback(false, aResp);
373 }
374 }
375 }
376 }
377 }
378 }
379 }
380 },
381 "xyz.openbmc_project.LED.GroupManager",
382 "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
383 "GetManagedObjects");
384}
385
386template <typename CallbackFunc>
387void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
388{
389 BMCWEB_LOG_DEBUG << "Get identify led properties";
390 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700391 [aResp,
392 callback{std::move(callback)}](const boost::system::error_code ec,
393 const PropertiesType &properties) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700394 if (ec)
395 {
396 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
397 aResp->res.result(
398 boost::beast::http::status::internal_server_error);
399 return;
400 }
401 BMCWEB_LOG_DEBUG << "Got " << properties.size()
402 << "led properties.";
403 std::string output;
404 for (const auto &property : properties)
405 {
406 if (property.first == "State")
407 {
408 const std::string *s =
409 mapbox::getPtr<std::string>(property.second);
410 if (nullptr != s)
411 {
412 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
413 const auto pos = s->rfind('.');
414 if (pos != std::string::npos)
415 {
416 auto led = s->substr(pos + 1);
417 for (const std::pair<const char *, const char *>
418 &p :
419 std::array<
420 std::pair<const char *, const char *>, 3>{
421 {{"On", "Lit"},
422 {"Blink", "Blinking"},
423 {"Off", "Off"}}})
424 {
425 if (led == p.first)
426 {
427 output = p.second;
428 }
429 }
430 }
431 }
432 }
433 }
434 callback(output, aResp);
435 },
436 "xyz.openbmc_project.LED.Controller.identify",
437 "/xyz/openbmc_project/led/physical/identify",
438 "org.freedesktop.DBus.Properties", "GetAll",
439 "xyz.openbmc_project.Led.Physical");
440}
441
442/**
443 * @brief Retrieves host state properties over dbus
444 *
445 * @param[in] aResp Shared pointer for completing asynchronous calls.
446 *
447 * @return None.
448 */
449void getHostState(std::shared_ptr<AsyncResp> aResp)
450{
451 BMCWEB_LOG_DEBUG << "Get host information.";
452 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700453 [aResp{std::move(aResp)}](
454 const boost::system::error_code ec,
455 const sdbusplus::message::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700456 if (ec)
457 {
458 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
459 aResp->res.result(
460 boost::beast::http::status::internal_server_error);
461 return;
462 }
Ed Tanous66173382018-08-15 18:20:59 -0700463
464 const std::string *s = mapbox::getPtr<const std::string>(hostState);
465 BMCWEB_LOG_DEBUG << "Host state: " << *s;
466 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700467 {
Ed Tanous66173382018-08-15 18:20:59 -0700468 // Verify Host State
469 if (*s == "xyz.openbmc_project.State.Host.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700470 {
Ed Tanous66173382018-08-15 18:20:59 -0700471 aResp->res.jsonValue["PowerState"] = "On";
472 aResp->res.jsonValue["Status"]["State"] = "Enabled";
473 }
474 else
475 {
476 aResp->res.jsonValue["PowerState"] = "Off";
477 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700478 }
479 }
480 },
481 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700482 "org.freedesktop.DBus.Properties", "Get",
483 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700484}
485
486/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200487 * SystemsCollection derived class for delivering ComputerSystems Collection
488 * Schema
489 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700490class SystemsCollection : public Node
491{
492 public:
493 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
494 {
495 Node::json["@odata.type"] =
496 "#ComputerSystemCollection.ComputerSystemCollection";
497 Node::json["@odata.id"] = "/redfish/v1/Systems";
498 Node::json["@odata.context"] =
499 "/redfish/v1/"
500 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
501 Node::json["Name"] = "Computer System Collection";
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200502
Ed Tanous1abe55e2018-09-05 08:30:59 -0700503 entityPrivileges = {
504 {boost::beast::http::verb::get, {{"Login"}}},
505 {boost::beast::http::verb::head, {{"Login"}}},
506 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
507 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
508 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
509 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
510 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200511
Ed Tanous1abe55e2018-09-05 08:30:59 -0700512 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700513 void doGet(crow::Response &res, const crow::Request &req,
514 const std::vector<std::string> &params) override
515 {
Ed Tanous66173382018-08-15 18:20:59 -0700516 BMCWEB_LOG_DEBUG << "Get list of available boards.";
517 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
518 res.jsonValue = Node::json;
519 crow::connections::systemBus->async_method_call(
520 [asyncResp](const boost::system::error_code ec,
521 const std::vector<std::string> &resp) {
522 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700523 {
Ed Tanous66173382018-08-15 18:20:59 -0700524 asyncResp->res.result(
525 boost::beast::http::status::internal_server_error);
526 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700527 }
Ed Tanous66173382018-08-15 18:20:59 -0700528 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
529
530 // ... prepare json array with appropriate @odata.id links
531 nlohmann::json &boardArray =
532 asyncResp->res.jsonValue["Members"];
533 boardArray = nlohmann::json::array();
534
535 // Iterate over all retrieved ObjectPaths.
536 for (const std::string &objpath : resp)
537 {
538 std::size_t lastPos = objpath.rfind("/");
539 if (lastPos != std::string::npos)
540 {
541 boardArray.push_back(
542 {{"@odata.id", "/redfish/v1/Systems/" +
543 objpath.substr(lastPos + 1)}});
544 }
545 }
546
547 asyncResp->res.jsonValue["Members@odata.count"] =
548 boardArray.size();
549 },
550 "xyz.openbmc_project.ObjectMapper",
551 "/xyz/openbmc_project/object_mapper",
552 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
553 "/xyz/openbmc_project/inventory", int32_t(0),
554 std::array<const char *, 1>{
555 "xyz.openbmc_project.Inventory.Item.Board"});
Ed Tanous1abe55e2018-09-05 08:30:59 -0700556 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200557};
558
559/**
Ed Tanouscc340dd2018-08-29 13:43:38 -0700560 * SystemActionsReset class supports handle POST method for Reset action.
561 * The class retrieves and sends data directly to D-Bus.
562 */
563class SystemActionsReset : public Node
564{
565 public:
566 SystemActionsReset(CrowApp &app) :
567 Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
568 std::string())
569 {
570 entityPrivileges = {
571 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
572 }
573
574 private:
575 /**
576 * Function handles POST method request.
577 * Analyzes POST body message before sends Reset request data to D-Bus.
578 */
579 void doPost(crow::Response &res, const crow::Request &req,
580 const std::vector<std::string> &params) override
581 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700582 auto asyncResp = std::make_shared<AsyncResp>(res);
583
584 std::string resetType;
585 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -0700586 {
587 return;
588 }
589
Ed Tanous9712f8a2018-09-21 13:38:49 -0700590 if (resetType == "ForceOff")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700591 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700592 // Force off acts on the chassis
593 crow::connections::systemBus->async_method_call(
594 [asyncResp](const boost::system::error_code ec) {
595 if (ec)
596 {
597 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Ed Tanouscc340dd2018-08-29 13:43:38 -0700598 asyncResp->res.result(
Ed Tanous9712f8a2018-09-21 13:38:49 -0700599 boost::beast::http::status::internal_server_error);
600 return;
601 }
602 // TODO Consider support polling mechanism to verify
603 // status of host and chassis after execute the
604 // requested action.
605 BMCWEB_LOG_DEBUG << "Response with no content";
606 asyncResp->res.result(
607 boost::beast::http::status::no_content);
608 },
609 "xyz.openbmc_project.State.Chassis",
610 "/xyz/openbmc_project/state/chassis0",
611 "org.freedesktop.DBus.Properties", "Set",
612 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
613 sdbusplus::message::variant<std::string>{
614 "xyz.openbmc_project.State.Chassis.Transition.Off"});
615 return;
Ed Tanouscc340dd2018-08-29 13:43:38 -0700616 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700617 // all other actions operate on the host
618 std::string command;
619 // Execute Reset Action regarding to each reset type.
620 if (resetType == "On")
621 {
622 command = "xyz.openbmc_project.State.Host.Transition.On";
623 }
624 else if (resetType == "GracefulShutdown")
625 {
626 command = "xyz.openbmc_project.State.Host.Transition.Off";
627 }
628 else if (resetType == "GracefulRestart")
629 {
630 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
631 }
632 else
633 {
634 res.result(boost::beast::http::status::bad_request);
635 messages::addMessageToErrorJson(
636 asyncResp->res.jsonValue,
637 messages::actionParameterUnknown("Reset", resetType));
638 return;
639 }
640
641 crow::connections::systemBus->async_method_call(
642 [asyncResp](const boost::system::error_code ec) {
643 if (ec)
644 {
645 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
646 asyncResp->res.result(
647 boost::beast::http::status::internal_server_error);
648 return;
649 }
650 // TODO Consider support polling mechanism to verify
651 // status of host and chassis after execute the
652 // requested action.
653 BMCWEB_LOG_DEBUG << "Response with no content";
654 asyncResp->res.result(boost::beast::http::status::no_content);
655 },
656 "xyz.openbmc_project.State.Host",
657 "/xyz/openbmc_project/state/host0",
658 "org.freedesktop.DBus.Properties", "Set",
659 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
660 sdbusplus::message::variant<std::string>{command});
Ed Tanouscc340dd2018-08-29 13:43:38 -0700661 }
662};
663
664/**
Ed Tanous66173382018-08-15 18:20:59 -0700665 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200666 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700667class Systems : public Node
668{
669 public:
670 /*
671 * Default Constructor
672 */
673 Systems(CrowApp &app) :
674 Node(app, "/redfish/v1/Systems/<str>/", std::string())
675 {
676 Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
677 Node::json["@odata.context"] =
678 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
679 Node::json["SystemType"] = "Physical";
680 Node::json["Description"] = "Computer System";
681 Node::json["Boot"]["BootSourceOverrideEnabled"] =
682 "Disabled"; // TODO(Dawid), get real boot data
683 Node::json["Boot"]["BootSourceOverrideTarget"] =
684 "None"; // TODO(Dawid), get real boot data
685 Node::json["Boot"]["BootSourceOverrideMode"] =
686 "Legacy"; // TODO(Dawid), get real boot data
687 Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
688 {"None", "Pxe", "Hdd", "Cd",
689 "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
690 // data
Ed Tanous04a258f2018-10-15 08:00:41 -0700691 Node::json["ProcessorSummary"]["Count"] = 0;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700692 Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
693 Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
694 Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous1abe55e2018-09-05 08:30:59 -0700695 entityPrivileges = {
696 {boost::beast::http::verb::get, {{"Login"}}},
697 {boost::beast::http::verb::head, {{"Login"}}},
698 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
699 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
700 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
701 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200702 }
703
Ed Tanous1abe55e2018-09-05 08:30:59 -0700704 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700705 /**
706 * Functions triggers appropriate requests on DBus
707 */
708 void doGet(crow::Response &res, const crow::Request &req,
709 const std::vector<std::string> &params) override
710 {
711 // Check if there is required param, truly entering this shall be
712 // impossible
713 if (params.size() != 1)
714 {
715 res.result(boost::beast::http::status::internal_server_error);
716 res.end();
717 return;
718 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200719
Ed Tanous1abe55e2018-09-05 08:30:59 -0700720 const std::string &name = params[0];
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200721
Ed Tanous04a258f2018-10-15 08:00:41 -0700722 res.jsonValue = Node::json;
723 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
724
Ed Tanouscc340dd2018-08-29 13:43:38 -0700725 // TODO Need to support ForceRestart.
726 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
727 {"target",
728 "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
729 {"ResetType@Redfish.AllowableValues",
730 {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200731
Ed Tanousa0803ef2018-08-29 13:29:23 -0700732 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700733
Ed Tanous6c34de42018-08-29 13:37:36 -0700734 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700735 asyncResp,
736 [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700737 if (asserted)
738 {
739 // If led group is asserted, then another call is needed to
740 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -0700741 getLedIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700742 aResp, [](const std::string &ledStatus,
743 const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700744 if (!ledStatus.empty())
745 {
746 aResp->res.jsonValue["IndicatorLED"] =
747 ledStatus;
748 }
749 });
750 }
751 else
752 {
753 aResp->res.jsonValue["IndicatorLED"] = "Off";
754 }
755 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700756 getComputerSystem(asyncResp, name);
757 getHostState(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200758 }
759
Ed Tanous1abe55e2018-09-05 08:30:59 -0700760 void doPatch(crow::Response &res, const crow::Request &req,
761 const std::vector<std::string> &params) override
762 {
763 // Check if there is required param, truly entering this shall be
764 // impossible
Ed Tanous66173382018-08-15 18:20:59 -0700765 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700766 if (params.size() != 1)
767 {
768 res.result(boost::beast::http::status::internal_server_error);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700769 return;
770 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700771
Ed Tanous66173382018-08-15 18:20:59 -0700772 const std::string &name = params[0];
773
Ed Tanous1abe55e2018-09-05 08:30:59 -0700774 res.jsonValue = Node::json;
775 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
776
Ed Tanous9712f8a2018-09-21 13:38:49 -0700777 std::string indicatorLedTemp;
778 boost::optional<std::string> indicatorLed = indicatorLedTemp;
779 if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
Ed Tanous66173382018-08-15 18:20:59 -0700780 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700781 return;
782 }
783
784 if (indicatorLed)
785 {
786 std::string dbusLedState;
787 if (*indicatorLed == "On")
Ed Tanous66173382018-08-15 18:20:59 -0700788 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700789 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
790 }
791 else if (*indicatorLed == "Blink")
792 {
793 dbusLedState =
794 "xyz.openbmc_project.Led.Physical.Action.Blinking";
795 }
796 else if (*indicatorLed == "Off")
797 {
798 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -0700799 }
800 else
801 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700802 messages::addMessageToJsonRoot(
803 res.jsonValue, messages::propertyValueNotInList(
804 *indicatorLed, "IndicatorLED"));
Ed Tanous66173382018-08-15 18:20:59 -0700805 return;
806 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700807
808 getHostState(asyncResp);
809 getComputerSystem(asyncResp, name);
810
811 // Update led group
812 BMCWEB_LOG_DEBUG << "Update led group.";
813 crow::connections::systemBus->async_method_call(
814 [asyncResp{std::move(asyncResp)}](
815 const boost::system::error_code ec) {
816 if (ec)
817 {
818 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
819 asyncResp->res.result(
820 boost::beast::http::status::internal_server_error);
821 return;
822 }
823 BMCWEB_LOG_DEBUG << "Led group update done.";
824 },
825 "xyz.openbmc_project.LED.GroupManager",
826 "/xyz/openbmc_project/led/groups/enclosure_identify",
827 "org.freedesktop.DBus.Properties", "Set",
828 "xyz.openbmc_project.Led.Group", "Asserted",
829 sdbusplus::message::variant<bool>(
830 (dbusLedState ==
831 "xyz.openbmc_project.Led.Physical.Action.Off"
832 ? false
833 : true)));
834 // Update identify led status
835 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
836 crow::connections::systemBus->async_method_call(
837 [asyncResp{std::move(asyncResp)},
838 indicatorLed{std::move(*indicatorLed)}](
839 const boost::system::error_code ec) {
840 if (ec)
841 {
842 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
843 asyncResp->res.result(
844 boost::beast::http::status::internal_server_error);
845 return;
846 }
847 BMCWEB_LOG_DEBUG << "Led state update done.";
848 asyncResp->res.jsonValue["IndicatorLED"] =
849 std::move(indicatorLed);
850 },
851 "xyz.openbmc_project.LED.Controller.identify",
852 "/xyz/openbmc_project/led/physical/identify",
853 "org.freedesktop.DBus.Properties", "Set",
854 "xyz.openbmc_project.Led.Physical", "State",
855 sdbusplus::message::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -0700856 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200857 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200858};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700859} // namespace redfish