blob: 12f15d1d1ba3e28da72d287074d6d3e8265e289c [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";
Jason M. Billsf12894f2018-10-09 12:45:45 -070047 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -070048 return;
49 }
50 bool foundName = false;
51 // Iterate over all retrieved ObjectPaths.
52 for (const std::pair<std::string,
53 std::vector<std::pair<
54 std::string, std::vector<std::string>>>>
55 &object : subtree)
56 {
57 const std::string &path = object.first;
58 BMCWEB_LOG_DEBUG << "Got path: " << path;
59 const std::vector<
60 std::pair<std::string, std::vector<std::string>>>
61 &connectionNames = object.second;
62 if (connectionNames.size() < 1)
63 {
64 continue;
65 }
66 // Check if computer system exist
67 if (boost::ends_with(path, name))
68 {
69 foundName = true;
70 BMCWEB_LOG_DEBUG << "Found name: " << name;
71 const std::string connectionName = connectionNames[0].first;
72 crow::connections::systemBus->async_method_call(
73 [aResp, name(std::string(name))](
74 const boost::system::error_code ec,
75 const std::vector<std::pair<
76 std::string, VariantType>> &propertiesList) {
77 if (ec)
78 {
79 BMCWEB_LOG_ERROR << "DBUS response error: "
80 << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -070081 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -070082 return;
83 }
84 BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
85 << "properties for system";
86 for (const std::pair<std::string, VariantType>
87 &property : propertiesList)
88 {
89 const std::string *value =
Ed Tanous1b6b96c2018-11-30 11:35:41 -080090 sdbusplus::message::variant_ns::get_if<
91 std::string>(&property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -070092 if (value != nullptr)
93 {
94 aResp->res.jsonValue[property.first] =
95 *value;
96 }
97 }
98 aResp->res.jsonValue["Name"] = name;
99 aResp->res.jsonValue["Id"] =
100 aResp->res.jsonValue["SerialNumber"];
101 },
102 connectionName, path, "org.freedesktop.DBus.Properties",
103 "GetAll",
104 "xyz.openbmc_project.Inventory.Decorator.Asset");
105 }
106 else
107 {
108 // This is not system, so check if it's cpu, dimm, UUID or
109 // BiosVer
Ed Tanous04a258f2018-10-15 08:00:41 -0700110 for (const auto &connection : connectionNames)
Ed Tanous6c34de42018-08-29 13:37:36 -0700111 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700112 for (const auto &interfaceName : connection.second)
Ed Tanous6c34de42018-08-29 13:37:36 -0700113 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700114 if (interfaceName ==
115 "xyz.openbmc_project.Inventory.Item.Dimm")
Ed Tanous6c34de42018-08-29 13:37:36 -0700116 {
117 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700118 << "Found Dimm, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700119 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700120 [aResp](
Ed Tanous6c34de42018-08-29 13:37:36 -0700121 const boost::system::error_code ec,
122 const std::vector<
123 std::pair<std::string, VariantType>>
124 &properties) {
125 if (ec)
126 {
127 BMCWEB_LOG_ERROR
128 << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700129 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700130 return;
131 }
132 BMCWEB_LOG_DEBUG << "Got "
133 << properties.size()
134 << "Dimm properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700135 for (const std::pair<std::string,
136 VariantType>
137 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700138 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700139 if (property.first ==
140 "MemorySizeInKb")
Ed Tanous6c34de42018-08-29 13:37:36 -0700141 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700142 const uint64_t *value =
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800143 sdbusplus::message::
144 variant_ns::get_if<
145 uint64_t>(
146 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700147 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700148 {
Ed Tanous6c34de42018-08-29 13:37:36 -0700149 aResp->res.jsonValue
150 ["TotalSystemMemoryGi"
151 "B"] +=
Ed Tanous04a258f2018-10-15 08:00:41 -0700152 *value / (1024 * 1024);
Ed Tanous6c34de42018-08-29 13:37:36 -0700153 aResp->res.jsonValue
154 ["MemorySummary"]
155 ["Status"]["State"] =
156 "Enabled";
157 }
158 }
159 }
160 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700161 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700162 "org.freedesktop.DBus.Properties", "GetAll",
163 "xyz.openbmc_project.Inventory.Item.Dimm");
164 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700165 else if (interfaceName ==
166 "xyz.openbmc_project.Inventory.Item.Cpu")
Ed Tanous6c34de42018-08-29 13:37:36 -0700167 {
168 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700169 << "Found Cpu, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700170 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700171 [aResp](
Ed Tanous6c34de42018-08-29 13:37:36 -0700172 const boost::system::error_code ec,
173 const std::vector<
174 std::pair<std::string, VariantType>>
175 &properties) {
176 if (ec)
177 {
178 BMCWEB_LOG_ERROR
179 << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700180 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700181 return;
182 }
183 BMCWEB_LOG_DEBUG << "Got "
184 << properties.size()
185 << "Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700186 for (const auto &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700187 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700188 if (property.first ==
189 "ProcessorFamily")
Ed Tanous6c34de42018-08-29 13:37:36 -0700190 {
191 const std::string *value =
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800192 sdbusplus::message::
193 variant_ns::get_if<
194 std::string>(
195 &property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700196 if (value != nullptr)
197 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700198 nlohmann::json
199 &procSummary =
200 aResp->res.jsonValue
Ed Tanous6c34de42018-08-29 13:37:36 -0700201 ["ProcessorSumm"
Ed Tanous04a258f2018-10-15 08:00:41 -0700202 "ary"];
203 nlohmann::json &procCount =
204 procSummary["Count"];
205
206 procCount =
207 procCount.get<int>() +
Ed Tanous6c34de42018-08-29 13:37:36 -0700208 1;
Ed Tanous04a258f2018-10-15 08:00:41 -0700209 procSummary["Status"]
210 ["State"] =
211 "Enabled";
212 procSummary["Model"] =
213 *value;
Ed Tanous6c34de42018-08-29 13:37:36 -0700214 }
215 }
216 }
217 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700218 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700219 "org.freedesktop.DBus.Properties", "GetAll",
220 "xyz.openbmc_project.Inventory.Item.Cpu");
221 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700222 else if (interfaceName ==
223 "xyz.openbmc_project.Common.UUID")
Ed Tanous6c34de42018-08-29 13:37:36 -0700224 {
225 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700226 << "Found UUID, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700227 crow::connections::systemBus->async_method_call(
228 [aResp](
229 const boost::system::error_code ec,
230 const std::vector<
231 std::pair<std::string, VariantType>>
232 &properties) {
233 if (ec)
234 {
235 BMCWEB_LOG_DEBUG
236 << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700237 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700238 return;
239 }
240 BMCWEB_LOG_DEBUG << "Got "
241 << properties.size()
242 << "UUID properties.";
243 for (const std::pair<std::string,
Ed Tanous04a258f2018-10-15 08:00:41 -0700244 VariantType>
245 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700246 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700247 if (property.first == "BIOSVer")
Ed Tanous6c34de42018-08-29 13:37:36 -0700248 {
249 const std::string *value =
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800250 sdbusplus::message::
251 variant_ns::get_if<
252 std::string>(
253 &property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700254 if (value != nullptr)
255 {
256 aResp->res.jsonValue
257 ["BiosVersion"] =
258 *value;
259 }
260 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700261 if (property.first == "UUID")
Ed Tanous6c34de42018-08-29 13:37:36 -0700262 {
263 const std::string *value =
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800264 sdbusplus::message::
265 variant_ns::get_if<
266 std::string>(
267 &property.second);
Ed Tanous04a258f2018-10-15 08:00:41 -0700268
Ed Tanous6c34de42018-08-29 13:37:36 -0700269 if (value != nullptr)
270 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700271 std::string valueStr =
272 *value;
273 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700274 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700275 valueStr.insert(8, 1,
276 '-');
277 valueStr.insert(13, 1,
278 '-');
279 valueStr.insert(18, 1,
280 '-');
281 valueStr.insert(23, 1,
282 '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700283 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700284 BMCWEB_LOG_DEBUG
285 << "UUID = "
286 << valueStr;
287 aResp->res
288 .jsonValue["UUID"] =
289 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700290 }
291 }
292 }
293 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700294 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700295 "org.freedesktop.DBus.Properties", "GetAll",
296 "xyz.openbmc_project.Common.UUID");
297 }
298 }
299 }
300 }
301 }
302 if (foundName == false)
303 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700304 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700305 }
306 },
307 "xyz.openbmc_project.ObjectMapper",
308 "/xyz/openbmc_project/object_mapper",
309 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700310 "/xyz/openbmc_project/inventory", int32_t(0),
311 std::array<const char *, 5>{
312 "xyz.openbmc_project.Inventory.Decorator.Asset",
313 "xyz.openbmc_project.Inventory.Item.Cpu",
314 "xyz.openbmc_project.Inventory.Item.Dimm",
315 "xyz.openbmc_project.Inventory.Item.System",
316 "xyz.openbmc_project.Common.UUID",
317 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700318}
319
320/**
321 * @brief Retrieves identify led group properties over dbus
322 *
323 * @param[in] aResp Shared pointer for completing asynchronous calls.
324 * @param[in] callback Callback for process retrieved data.
325 *
326 * @return None.
327 */
328template <typename CallbackFunc>
329void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
330 CallbackFunc &&callback)
331{
332 BMCWEB_LOG_DEBUG << "Get led groups";
333 crow::connections::systemBus->async_method_call(
334 [aResp{std::move(aResp)},
Ed Tanous66173382018-08-15 18:20:59 -0700335 callback{std::move(callback)}](const boost::system::error_code &ec,
336 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700337 if (ec)
338 {
339 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700340 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700341 return;
342 }
343 BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
344 for (const auto &objPath : resp)
345 {
346 const std::string &path = objPath.first;
347 if (path.rfind("enclosure_identify") != std::string::npos)
348 {
349 for (const auto &interface : objPath.second)
350 {
351 if (interface.first == "xyz.openbmc_project.Led.Group")
352 {
353 for (const auto &property : interface.second)
354 {
355 if (property.first == "Asserted")
356 {
357 const bool *asserted =
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800358 sdbusplus::message::variant_ns::get_if<
359 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 Tanous1b6b96c2018-11-30 11:35:41 -0800402 sdbusplus::message::variant_ns::get_if<std::string>(
403 &property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700404 if (nullptr != s)
405 {
406 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
407 const auto pos = s->rfind('.');
408 if (pos != std::string::npos)
409 {
410 auto led = s->substr(pos + 1);
411 for (const std::pair<const char *, const char *>
412 &p :
413 std::array<
414 std::pair<const char *, const char *>, 3>{
415 {{"On", "Lit"},
416 {"Blink", "Blinking"},
417 {"Off", "Off"}}})
418 {
419 if (led == p.first)
420 {
421 output = p.second;
422 }
423 }
424 }
425 }
426 }
427 }
428 callback(output, aResp);
429 },
430 "xyz.openbmc_project.LED.Controller.identify",
431 "/xyz/openbmc_project/led/physical/identify",
432 "org.freedesktop.DBus.Properties", "GetAll",
433 "xyz.openbmc_project.Led.Physical");
434}
435
436/**
437 * @brief Retrieves host state properties over dbus
438 *
439 * @param[in] aResp Shared pointer for completing asynchronous calls.
440 *
441 * @return None.
442 */
443void getHostState(std::shared_ptr<AsyncResp> aResp)
444{
445 BMCWEB_LOG_DEBUG << "Get host information.";
446 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700447 [aResp{std::move(aResp)}](
448 const boost::system::error_code ec,
449 const sdbusplus::message::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700450 if (ec)
451 {
452 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700453 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700454 return;
455 }
Ed Tanous66173382018-08-15 18:20:59 -0700456
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800457 const std::string *s =
458 sdbusplus::message::variant_ns::get_if<std::string>(&hostState);
Ed Tanous66173382018-08-15 18:20:59 -0700459 BMCWEB_LOG_DEBUG << "Host state: " << *s;
460 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700461 {
Ed Tanous66173382018-08-15 18:20:59 -0700462 // Verify Host State
463 if (*s == "xyz.openbmc_project.State.Host.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700464 {
Ed Tanous66173382018-08-15 18:20:59 -0700465 aResp->res.jsonValue["PowerState"] = "On";
466 aResp->res.jsonValue["Status"]["State"] = "Enabled";
467 }
468 else
469 {
470 aResp->res.jsonValue["PowerState"] = "Off";
471 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700472 }
473 }
474 },
475 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700476 "org.freedesktop.DBus.Properties", "Get",
477 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700478}
479
480/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200481 * SystemsCollection derived class for delivering ComputerSystems Collection
482 * Schema
483 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700484class SystemsCollection : public Node
485{
486 public:
487 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
488 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700489 entityPrivileges = {
490 {boost::beast::http::verb::get, {{"Login"}}},
491 {boost::beast::http::verb::head, {{"Login"}}},
492 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
493 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
494 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
495 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
496 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200497
Ed Tanous1abe55e2018-09-05 08:30:59 -0700498 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700499 void doGet(crow::Response &res, const crow::Request &req,
500 const std::vector<std::string> &params) override
501 {
Ed Tanous66173382018-08-15 18:20:59 -0700502 BMCWEB_LOG_DEBUG << "Get list of available boards.";
503 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -0800504 res.jsonValue["@odata.type"] =
505 "#ComputerSystemCollection.ComputerSystemCollection";
506 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
507 res.jsonValue["@odata.context"] =
508 "/redfish/v1/"
509 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
510 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous66173382018-08-15 18:20:59 -0700511 crow::connections::systemBus->async_method_call(
512 [asyncResp](const boost::system::error_code ec,
513 const std::vector<std::string> &resp) {
514 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700515 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700516 messages::internalError(asyncResp->res);
Ed Tanous66173382018-08-15 18:20:59 -0700517 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700518 }
Ed Tanous66173382018-08-15 18:20:59 -0700519 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
520
521 // ... prepare json array with appropriate @odata.id links
522 nlohmann::json &boardArray =
523 asyncResp->res.jsonValue["Members"];
524 boardArray = nlohmann::json::array();
525
526 // Iterate over all retrieved ObjectPaths.
527 for (const std::string &objpath : resp)
528 {
529 std::size_t lastPos = objpath.rfind("/");
530 if (lastPos != std::string::npos)
531 {
532 boardArray.push_back(
533 {{"@odata.id", "/redfish/v1/Systems/" +
534 objpath.substr(lastPos + 1)}});
535 }
536 }
537
538 asyncResp->res.jsonValue["Members@odata.count"] =
539 boardArray.size();
540 },
541 "xyz.openbmc_project.ObjectMapper",
542 "/xyz/openbmc_project/object_mapper",
543 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
544 "/xyz/openbmc_project/inventory", int32_t(0),
545 std::array<const char *, 1>{
546 "xyz.openbmc_project.Inventory.Item.Board"});
Ed Tanous1abe55e2018-09-05 08:30:59 -0700547 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200548};
549
550/**
Ed Tanouscc340dd2018-08-29 13:43:38 -0700551 * SystemActionsReset class supports handle POST method for Reset action.
552 * The class retrieves and sends data directly to D-Bus.
553 */
554class SystemActionsReset : public Node
555{
556 public:
557 SystemActionsReset(CrowApp &app) :
558 Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
559 std::string())
560 {
561 entityPrivileges = {
562 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
563 }
564
565 private:
566 /**
567 * Function handles POST method request.
568 * Analyzes POST body message before sends Reset request data to D-Bus.
569 */
570 void doPost(crow::Response &res, const crow::Request &req,
571 const std::vector<std::string> &params) override
572 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700573 auto asyncResp = std::make_shared<AsyncResp>(res);
574
575 std::string resetType;
576 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -0700577 {
578 return;
579 }
580
Ed Tanous9712f8a2018-09-21 13:38:49 -0700581 if (resetType == "ForceOff")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700582 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700583 // Force off acts on the chassis
584 crow::connections::systemBus->async_method_call(
585 [asyncResp](const boost::system::error_code ec) {
586 if (ec)
587 {
588 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700589 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700590 return;
591 }
592 // TODO Consider support polling mechanism to verify
593 // status of host and chassis after execute the
594 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700595 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700596 },
597 "xyz.openbmc_project.State.Chassis",
598 "/xyz/openbmc_project/state/chassis0",
599 "org.freedesktop.DBus.Properties", "Set",
600 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
601 sdbusplus::message::variant<std::string>{
602 "xyz.openbmc_project.State.Chassis.Transition.Off"});
603 return;
Ed Tanouscc340dd2018-08-29 13:43:38 -0700604 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700605 // all other actions operate on the host
606 std::string command;
607 // Execute Reset Action regarding to each reset type.
608 if (resetType == "On")
609 {
610 command = "xyz.openbmc_project.State.Host.Transition.On";
611 }
612 else if (resetType == "GracefulShutdown")
613 {
614 command = "xyz.openbmc_project.State.Host.Transition.Off";
615 }
616 else if (resetType == "GracefulRestart")
617 {
618 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
619 }
620 else
621 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700622 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700623 return;
624 }
625
626 crow::connections::systemBus->async_method_call(
627 [asyncResp](const boost::system::error_code ec) {
628 if (ec)
629 {
630 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700631 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700632 return;
633 }
634 // TODO Consider support polling mechanism to verify
635 // status of host and chassis after execute the
636 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700637 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700638 },
639 "xyz.openbmc_project.State.Host",
640 "/xyz/openbmc_project/state/host0",
641 "org.freedesktop.DBus.Properties", "Set",
642 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
643 sdbusplus::message::variant<std::string>{command});
Ed Tanouscc340dd2018-08-29 13:43:38 -0700644 }
645};
646
647/**
Ed Tanous66173382018-08-15 18:20:59 -0700648 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200649 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700650class Systems : public Node
651{
652 public:
653 /*
654 * Default Constructor
655 */
656 Systems(CrowApp &app) :
657 Node(app, "/redfish/v1/Systems/<str>/", std::string())
658 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700659 entityPrivileges = {
660 {boost::beast::http::verb::get, {{"Login"}}},
661 {boost::beast::http::verb::head, {{"Login"}}},
662 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
663 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
664 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
665 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200666 }
667
Ed Tanous1abe55e2018-09-05 08:30:59 -0700668 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700669 /**
670 * Functions triggers appropriate requests on DBus
671 */
672 void doGet(crow::Response &res, const crow::Request &req,
673 const std::vector<std::string> &params) override
674 {
675 // Check if there is required param, truly entering this shall be
676 // impossible
677 if (params.size() != 1)
678 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700679 messages::internalError(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700680 res.end();
681 return;
682 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200683
Ed Tanous1abe55e2018-09-05 08:30:59 -0700684 const std::string &name = params[0];
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200685
Ed Tanous0f74e642018-11-12 15:17:05 -0800686 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
687 res.jsonValue["@odata.context"] =
688 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
689 res.jsonValue["SystemType"] = "Physical";
690 res.jsonValue["Description"] = "Computer System";
691 res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
692 "Disabled"; // TODO(Dawid), get real boot data
693 res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
694 "None"; // TODO(Dawid), get real boot data
695 res.jsonValue["Boot"]["BootSourceOverrideMode"] =
696 "Legacy"; // TODO(Dawid), get real boot data
697 res.jsonValue["Boot"]
698 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
699 "None", "Pxe", "Hdd", "Cd",
700 "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
701 // data
702 res.jsonValue["ProcessorSummary"]["Count"] = 0;
703 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
704 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
705 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous04a258f2018-10-15 08:00:41 -0700706 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
707
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200708 res.jsonValue["Processors"] = {
709 {"@odata.id", "/redfish/v1/Systems/" + name + "/Processors"}};
710 res.jsonValue["Memory"] = {
711 {"@odata.id", "/redfish/v1/Systems/" + name + "/Memory"}};
Ed Tanouscc340dd2018-08-29 13:43:38 -0700712 // TODO Need to support ForceRestart.
713 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
714 {"target",
715 "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
716 {"ResetType@Redfish.AllowableValues",
717 {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200718
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800719 res.jsonValue["LogServices"] = {
720 {"@odata.id", "/redfish/v1/Systems/" + name + "/LogServices"}};
721
Ed Tanousa0803ef2018-08-29 13:29:23 -0700722 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700723
Ed Tanous6c34de42018-08-29 13:37:36 -0700724 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700725 asyncResp,
726 [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700727 if (asserted)
728 {
729 // If led group is asserted, then another call is needed to
730 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -0700731 getLedIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700732 aResp, [](const std::string &ledStatus,
733 const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700734 if (!ledStatus.empty())
735 {
736 aResp->res.jsonValue["IndicatorLED"] =
737 ledStatus;
738 }
739 });
740 }
741 else
742 {
743 aResp->res.jsonValue["IndicatorLED"] = "Off";
744 }
745 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700746 getComputerSystem(asyncResp, name);
747 getHostState(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200748 }
749
Ed Tanous1abe55e2018-09-05 08:30:59 -0700750 void doPatch(crow::Response &res, const crow::Request &req,
751 const std::vector<std::string> &params) override
752 {
753 // Check if there is required param, truly entering this shall be
754 // impossible
Ed Tanous66173382018-08-15 18:20:59 -0700755 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700756 if (params.size() != 1)
757 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700758 messages::internalError(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700759 return;
760 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700761
Ed Tanous66173382018-08-15 18:20:59 -0700762 const std::string &name = params[0];
763
Ed Tanous0f74e642018-11-12 15:17:05 -0800764 messages::success(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700765
Ed Tanous9712f8a2018-09-21 13:38:49 -0700766 std::string indicatorLedTemp;
767 boost::optional<std::string> indicatorLed = indicatorLedTemp;
768 if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
Ed Tanous66173382018-08-15 18:20:59 -0700769 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700770 return;
771 }
772
773 if (indicatorLed)
774 {
775 std::string dbusLedState;
776 if (*indicatorLed == "On")
Ed Tanous66173382018-08-15 18:20:59 -0700777 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700778 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
779 }
780 else if (*indicatorLed == "Blink")
781 {
782 dbusLedState =
783 "xyz.openbmc_project.Led.Physical.Action.Blinking";
784 }
785 else if (*indicatorLed == "Off")
786 {
787 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -0700788 }
789 else
790 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -0800791 messages::propertyValueNotInList(res, *indicatorLed,
792 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -0700793 return;
794 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700795
796 getHostState(asyncResp);
797 getComputerSystem(asyncResp, name);
798
799 // Update led group
800 BMCWEB_LOG_DEBUG << "Update led group.";
801 crow::connections::systemBus->async_method_call(
802 [asyncResp{std::move(asyncResp)}](
803 const boost::system::error_code ec) {
804 if (ec)
805 {
806 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700807 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700808 return;
809 }
810 BMCWEB_LOG_DEBUG << "Led group update done.";
811 },
812 "xyz.openbmc_project.LED.GroupManager",
813 "/xyz/openbmc_project/led/groups/enclosure_identify",
814 "org.freedesktop.DBus.Properties", "Set",
815 "xyz.openbmc_project.Led.Group", "Asserted",
816 sdbusplus::message::variant<bool>(
817 (dbusLedState ==
818 "xyz.openbmc_project.Led.Physical.Action.Off"
819 ? false
820 : true)));
821 // Update identify led status
822 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
823 crow::connections::systemBus->async_method_call(
824 [asyncResp{std::move(asyncResp)},
825 indicatorLed{std::move(*indicatorLed)}](
826 const boost::system::error_code ec) {
827 if (ec)
828 {
829 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700830 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700831 return;
832 }
833 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -0700834 },
835 "xyz.openbmc_project.LED.Controller.identify",
836 "/xyz/openbmc_project/led/physical/identify",
837 "org.freedesktop.DBus.Properties", "Set",
838 "xyz.openbmc_project.Led.Physical", "State",
839 sdbusplus::message::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -0700840 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200841 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200842};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700843} // namespace redfish