blob: b6c0512ebdb3682739ea6f701e88cbfba349fc22 [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 {
259 const std::string *value =
260 sdbusplus::message::variant_ns::
261 get_if<std::string>(
262 &property.second);
263 if (value != nullptr)
264 {
265 aResp->res
266 .jsonValue[property.first] =
267 *value;
268 }
269 }
270 aResp->res.jsonValue["Name"] = "system";
271 aResp->res.jsonValue["Id"] =
272 aResp->res.jsonValue["SerialNumber"];
273 },
274 connection.first, path,
275 "org.freedesktop.DBus.Properties", "GetAll",
276 "xyz.openbmc_project.Inventory.Decorator."
277 "Asset");
Ed Tanous6c34de42018-08-29 13:37:36 -0700278 }
279 }
280 }
281 }
Ed Tanous6c34de42018-08-29 13:37:36 -0700282 },
283 "xyz.openbmc_project.ObjectMapper",
284 "/xyz/openbmc_project/object_mapper",
285 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700286 "/xyz/openbmc_project/inventory", int32_t(0),
287 std::array<const char *, 5>{
288 "xyz.openbmc_project.Inventory.Decorator.Asset",
289 "xyz.openbmc_project.Inventory.Item.Cpu",
290 "xyz.openbmc_project.Inventory.Item.Dimm",
291 "xyz.openbmc_project.Inventory.Item.System",
292 "xyz.openbmc_project.Common.UUID",
293 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700294}
295
296/**
297 * @brief Retrieves identify led group properties over dbus
298 *
299 * @param[in] aResp Shared pointer for completing asynchronous calls.
300 * @param[in] callback Callback for process retrieved data.
301 *
302 * @return None.
303 */
304template <typename CallbackFunc>
305void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
306 CallbackFunc &&callback)
307{
308 BMCWEB_LOG_DEBUG << "Get led groups";
309 crow::connections::systemBus->async_method_call(
310 [aResp{std::move(aResp)},
Ed Tanous66173382018-08-15 18:20:59 -0700311 callback{std::move(callback)}](const boost::system::error_code &ec,
312 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700313 if (ec)
314 {
315 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700316 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700317 return;
318 }
319 BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
320 for (const auto &objPath : resp)
321 {
322 const std::string &path = objPath.first;
323 if (path.rfind("enclosure_identify") != std::string::npos)
324 {
325 for (const auto &interface : objPath.second)
326 {
327 if (interface.first == "xyz.openbmc_project.Led.Group")
328 {
329 for (const auto &property : interface.second)
330 {
331 if (property.first == "Asserted")
332 {
333 const bool *asserted =
Ed Tanousabf2add2019-01-22 16:40:12 -0800334 std::get_if<bool>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700335 if (nullptr != asserted)
336 {
337 callback(*asserted, aResp);
338 }
339 else
340 {
341 callback(false, aResp);
342 }
343 }
344 }
345 }
346 }
347 }
348 }
349 },
350 "xyz.openbmc_project.LED.GroupManager",
351 "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
352 "GetManagedObjects");
353}
354
355template <typename CallbackFunc>
356void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
357{
358 BMCWEB_LOG_DEBUG << "Get identify led properties";
359 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700360 [aResp,
361 callback{std::move(callback)}](const boost::system::error_code ec,
362 const PropertiesType &properties) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700363 if (ec)
364 {
365 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700366 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700367 return;
368 }
369 BMCWEB_LOG_DEBUG << "Got " << properties.size()
370 << "led properties.";
371 std::string output;
372 for (const auto &property : properties)
373 {
374 if (property.first == "State")
375 {
376 const std::string *s =
Ed Tanousabf2add2019-01-22 16:40:12 -0800377 std::get_if<std::string>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700378 if (nullptr != s)
379 {
380 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
381 const auto pos = s->rfind('.');
382 if (pos != std::string::npos)
383 {
384 auto led = s->substr(pos + 1);
385 for (const std::pair<const char *, const char *>
386 &p :
387 std::array<
388 std::pair<const char *, const char *>, 3>{
389 {{"On", "Lit"},
390 {"Blink", "Blinking"},
391 {"Off", "Off"}}})
392 {
393 if (led == p.first)
394 {
395 output = p.second;
396 }
397 }
398 }
399 }
400 }
401 }
402 callback(output, aResp);
403 },
404 "xyz.openbmc_project.LED.Controller.identify",
405 "/xyz/openbmc_project/led/physical/identify",
406 "org.freedesktop.DBus.Properties", "GetAll",
407 "xyz.openbmc_project.Led.Physical");
408}
409
410/**
411 * @brief Retrieves host state properties over dbus
412 *
413 * @param[in] aResp Shared pointer for completing asynchronous calls.
414 *
415 * @return None.
416 */
417void getHostState(std::shared_ptr<AsyncResp> aResp)
418{
419 BMCWEB_LOG_DEBUG << "Get host information.";
420 crow::connections::systemBus->async_method_call(
Ed Tanousabf2add2019-01-22 16:40:12 -0800421 [aResp{std::move(aResp)}](const boost::system::error_code ec,
422 const std::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700423 if (ec)
424 {
425 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700426 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700427 return;
428 }
Ed Tanous66173382018-08-15 18:20:59 -0700429
Ed Tanousabf2add2019-01-22 16:40:12 -0800430 const std::string *s = std::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700431 BMCWEB_LOG_DEBUG << "Host state: " << *s;
432 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700433 {
Ed Tanous66173382018-08-15 18:20:59 -0700434 // Verify Host State
Andrew Geissler94732662019-01-08 19:32:16 -0800435 if (*s == "xyz.openbmc_project.State.Host.HostState.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700436 {
Ed Tanous66173382018-08-15 18:20:59 -0700437 aResp->res.jsonValue["PowerState"] = "On";
438 aResp->res.jsonValue["Status"]["State"] = "Enabled";
439 }
440 else
441 {
442 aResp->res.jsonValue["PowerState"] = "Off";
443 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700444 }
445 }
446 },
447 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700448 "org.freedesktop.DBus.Properties", "Get",
449 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700450}
451
452/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200453 * SystemsCollection derived class for delivering ComputerSystems Collection
454 * Schema
455 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700456class SystemsCollection : public Node
457{
458 public:
459 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
460 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700461 entityPrivileges = {
462 {boost::beast::http::verb::get, {{"Login"}}},
463 {boost::beast::http::verb::head, {{"Login"}}},
464 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
465 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
466 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
467 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
468 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200469
Ed Tanous1abe55e2018-09-05 08:30:59 -0700470 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700471 void doGet(crow::Response &res, const crow::Request &req,
472 const std::vector<std::string> &params) override
473 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800474 res.jsonValue["@odata.type"] =
475 "#ComputerSystemCollection.ComputerSystemCollection";
476 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
477 res.jsonValue["@odata.context"] =
478 "/redfish/v1/"
479 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
480 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous029573d2019-02-01 10:57:49 -0800481 res.jsonValue["Members"] = {
482 {{"@odata.id", "/redfish/v1/Systems/system"}}};
483 res.jsonValue["Members@odata.count"] = 1;
484 res.end();
Ed Tanous1abe55e2018-09-05 08:30:59 -0700485 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200486};
487
488/**
Ed Tanouscc340dd2018-08-29 13:43:38 -0700489 * SystemActionsReset class supports handle POST method for Reset action.
490 * The class retrieves and sends data directly to D-Bus.
491 */
492class SystemActionsReset : public Node
493{
494 public:
495 SystemActionsReset(CrowApp &app) :
Ed Tanous029573d2019-02-01 10:57:49 -0800496 Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700497 {
498 entityPrivileges = {
499 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
500 }
501
502 private:
503 /**
504 * Function handles POST method request.
505 * Analyzes POST body message before sends Reset request data to D-Bus.
506 */
507 void doPost(crow::Response &res, const crow::Request &req,
508 const std::vector<std::string> &params) override
509 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700510 auto asyncResp = std::make_shared<AsyncResp>(res);
511
512 std::string resetType;
513 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -0700514 {
515 return;
516 }
517
Ed Tanous9712f8a2018-09-21 13:38:49 -0700518 if (resetType == "ForceOff")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700519 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700520 // Force off acts on the chassis
521 crow::connections::systemBus->async_method_call(
522 [asyncResp](const boost::system::error_code ec) {
523 if (ec)
524 {
525 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700526 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700527 return;
528 }
529 // TODO Consider support polling mechanism to verify
530 // status of host and chassis after execute the
531 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700532 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700533 },
534 "xyz.openbmc_project.State.Chassis",
535 "/xyz/openbmc_project/state/chassis0",
536 "org.freedesktop.DBus.Properties", "Set",
537 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
Ed Tanousabf2add2019-01-22 16:40:12 -0800538 std::variant<std::string>{
Ed Tanous9712f8a2018-09-21 13:38:49 -0700539 "xyz.openbmc_project.State.Chassis.Transition.Off"});
540 return;
Ed Tanouscc340dd2018-08-29 13:43:38 -0700541 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700542 // all other actions operate on the host
543 std::string command;
544 // Execute Reset Action regarding to each reset type.
545 if (resetType == "On")
546 {
547 command = "xyz.openbmc_project.State.Host.Transition.On";
548 }
549 else if (resetType == "GracefulShutdown")
550 {
551 command = "xyz.openbmc_project.State.Host.Transition.Off";
552 }
553 else if (resetType == "GracefulRestart")
554 {
555 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
556 }
557 else
558 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700559 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700560 return;
561 }
562
563 crow::connections::systemBus->async_method_call(
564 [asyncResp](const boost::system::error_code ec) {
565 if (ec)
566 {
567 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700568 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700569 return;
570 }
571 // TODO Consider support polling mechanism to verify
572 // status of host and chassis after execute the
573 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700574 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700575 },
576 "xyz.openbmc_project.State.Host",
577 "/xyz/openbmc_project/state/host0",
578 "org.freedesktop.DBus.Properties", "Set",
579 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
Ed Tanousabf2add2019-01-22 16:40:12 -0800580 std::variant<std::string>{command});
Ed Tanouscc340dd2018-08-29 13:43:38 -0700581 }
582};
583
584/**
Ed Tanous66173382018-08-15 18:20:59 -0700585 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200586 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700587class Systems : public Node
588{
589 public:
590 /*
591 * Default Constructor
592 */
Ed Tanous029573d2019-02-01 10:57:49 -0800593 Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
Ed Tanous1abe55e2018-09-05 08:30:59 -0700594 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700595 entityPrivileges = {
596 {boost::beast::http::verb::get, {{"Login"}}},
597 {boost::beast::http::verb::head, {{"Login"}}},
598 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
599 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
600 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
601 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200602 }
603
Ed Tanous1abe55e2018-09-05 08:30:59 -0700604 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700605 /**
606 * Functions triggers appropriate requests on DBus
607 */
608 void doGet(crow::Response &res, const crow::Request &req,
609 const std::vector<std::string> &params) override
610 {
Rapkiewicz, Pawelbb3d9942018-11-22 10:59:11 +0100611 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_5_1.ComputerSystem";
Ed Tanous0f74e642018-11-12 15:17:05 -0800612 res.jsonValue["@odata.context"] =
613 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
Ed Tanous029573d2019-02-01 10:57:49 -0800614 res.jsonValue["Name"] = "Computer System";
615 res.jsonValue["Id"] = "system";
Ed Tanous0f74e642018-11-12 15:17:05 -0800616 res.jsonValue["SystemType"] = "Physical";
617 res.jsonValue["Description"] = "Computer System";
618 res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
619 "Disabled"; // TODO(Dawid), get real boot data
620 res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
621 "None"; // TODO(Dawid), get real boot data
622 res.jsonValue["Boot"]["BootSourceOverrideMode"] =
623 "Legacy"; // TODO(Dawid), get real boot data
624 res.jsonValue["Boot"]
625 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
626 "None", "Pxe", "Hdd", "Cd",
627 "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
628 // data
629 res.jsonValue["ProcessorSummary"]["Count"] = 0;
630 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
631 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
632 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous029573d2019-02-01 10:57:49 -0800633 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
Ed Tanous04a258f2018-10-15 08:00:41 -0700634
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200635 res.jsonValue["Processors"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800636 {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200637 res.jsonValue["Memory"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800638 {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
639
Ed Tanouscc340dd2018-08-29 13:43:38 -0700640 // TODO Need to support ForceRestart.
641 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
642 {"target",
Ed Tanous029573d2019-02-01 10:57:49 -0800643 "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
Ed Tanouscc340dd2018-08-29 13:43:38 -0700644 {"ResetType@Redfish.AllowableValues",
645 {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200646
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800647 res.jsonValue["LogServices"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800648 {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800649
Ed Tanousa0803ef2018-08-29 13:29:23 -0700650 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700651
Ed Tanous6c34de42018-08-29 13:37:36 -0700652 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700653 asyncResp,
654 [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700655 if (asserted)
656 {
657 // If led group is asserted, then another call is needed to
658 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -0700659 getLedIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700660 aResp, [](const std::string &ledStatus,
661 const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700662 if (!ledStatus.empty())
663 {
664 aResp->res.jsonValue["IndicatorLED"] =
665 ledStatus;
666 }
667 });
668 }
669 else
670 {
671 aResp->res.jsonValue["IndicatorLED"] = "Off";
672 }
673 });
Ed Tanous029573d2019-02-01 10:57:49 -0800674 getComputerSystem(asyncResp);
Ed Tanous6c34de42018-08-29 13:37:36 -0700675 getHostState(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200676 }
677
Ed Tanous1abe55e2018-09-05 08:30:59 -0700678 void doPatch(crow::Response &res, const crow::Request &req,
679 const std::vector<std::string> &params) override
680 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700681 std::string indicatorLedTemp;
Ed Tanousa24526d2018-12-10 15:17:59 -0800682 std::optional<std::string> indicatorLed = indicatorLedTemp;
Ed Tanous9712f8a2018-09-21 13:38:49 -0700683 if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
Ed Tanous66173382018-08-15 18:20:59 -0700684 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700685 return;
686 }
Ed Tanous029573d2019-02-01 10:57:49 -0800687 auto asyncResp = std::make_shared<AsyncResp>(res);
688 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700689 if (indicatorLed)
690 {
691 std::string dbusLedState;
692 if (*indicatorLed == "On")
Ed Tanous66173382018-08-15 18:20:59 -0700693 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700694 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
695 }
696 else if (*indicatorLed == "Blink")
697 {
698 dbusLedState =
699 "xyz.openbmc_project.Led.Physical.Action.Blinking";
700 }
701 else if (*indicatorLed == "Off")
702 {
703 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -0700704 }
705 else
706 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -0800707 messages::propertyValueNotInList(res, *indicatorLed,
708 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -0700709 return;
710 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700711
712 getHostState(asyncResp);
Ed Tanous029573d2019-02-01 10:57:49 -0800713 getComputerSystem(asyncResp);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700714
715 // Update led group
716 BMCWEB_LOG_DEBUG << "Update led group.";
717 crow::connections::systemBus->async_method_call(
718 [asyncResp{std::move(asyncResp)}](
719 const boost::system::error_code ec) {
720 if (ec)
721 {
722 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700723 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700724 return;
725 }
726 BMCWEB_LOG_DEBUG << "Led group update done.";
727 },
728 "xyz.openbmc_project.LED.GroupManager",
729 "/xyz/openbmc_project/led/groups/enclosure_identify",
730 "org.freedesktop.DBus.Properties", "Set",
731 "xyz.openbmc_project.Led.Group", "Asserted",
Ed Tanousabf2add2019-01-22 16:40:12 -0800732 std::variant<bool>(
Ed Tanous9712f8a2018-09-21 13:38:49 -0700733 (dbusLedState ==
734 "xyz.openbmc_project.Led.Physical.Action.Off"
735 ? false
736 : true)));
737 // Update identify led status
738 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
739 crow::connections::systemBus->async_method_call(
740 [asyncResp{std::move(asyncResp)},
741 indicatorLed{std::move(*indicatorLed)}](
742 const boost::system::error_code ec) {
743 if (ec)
744 {
745 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700746 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700747 return;
748 }
749 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -0700750 },
751 "xyz.openbmc_project.LED.Controller.identify",
752 "/xyz/openbmc_project/led/physical/identify",
753 "org.freedesktop.DBus.Properties", "Set",
754 "xyz.openbmc_project.Led.Physical", "State",
Ed Tanousabf2add2019-01-22 16:40:12 -0800755 std::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -0700756 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200757 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200758};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700759} // namespace redfish