blob: 7d0cc0236e877e79987d3c9d47612e9b55cd2f2f [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 =
90 mapbox::getPtr<const std::string>(
91 property.second);
92 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 Tanous6c34de42018-08-29 13:37:36 -0700143 mapbox::getPtr<
Ed Tanous04a258f2018-10-15 08:00:41 -0700144 const uint64_t>(
145 property.second);
146 if (value != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700147 {
Ed Tanous6c34de42018-08-29 13:37:36 -0700148 aResp->res.jsonValue
149 ["TotalSystemMemoryGi"
150 "B"] +=
Ed Tanous04a258f2018-10-15 08:00:41 -0700151 *value / (1024 * 1024);
Ed Tanous6c34de42018-08-29 13:37:36 -0700152 aResp->res.jsonValue
153 ["MemorySummary"]
154 ["Status"]["State"] =
155 "Enabled";
156 }
157 }
158 }
159 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700160 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700161 "org.freedesktop.DBus.Properties", "GetAll",
162 "xyz.openbmc_project.Inventory.Item.Dimm");
163 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700164 else if (interfaceName ==
165 "xyz.openbmc_project.Inventory.Item.Cpu")
Ed Tanous6c34de42018-08-29 13:37:36 -0700166 {
167 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700168 << "Found Cpu, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700169 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700170 [aResp](
Ed Tanous6c34de42018-08-29 13:37:36 -0700171 const boost::system::error_code ec,
172 const std::vector<
173 std::pair<std::string, VariantType>>
174 &properties) {
175 if (ec)
176 {
177 BMCWEB_LOG_ERROR
178 << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700179 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700180 return;
181 }
182 BMCWEB_LOG_DEBUG << "Got "
183 << properties.size()
184 << "Cpu properties.";
Ed Tanous04a258f2018-10-15 08:00:41 -0700185 for (const auto &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700186 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700187 if (property.first ==
188 "ProcessorFamily")
Ed Tanous6c34de42018-08-29 13:37:36 -0700189 {
190 const std::string *value =
191 mapbox::getPtr<
192 const std::string>(
Ed Tanous04a258f2018-10-15 08:00:41 -0700193 property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700194 if (value != nullptr)
195 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700196 nlohmann::json
197 &procSummary =
198 aResp->res.jsonValue
Ed Tanous6c34de42018-08-29 13:37:36 -0700199 ["ProcessorSumm"
Ed Tanous04a258f2018-10-15 08:00:41 -0700200 "ary"];
201 nlohmann::json &procCount =
202 procSummary["Count"];
203
204 procCount =
205 procCount.get<int>() +
Ed Tanous6c34de42018-08-29 13:37:36 -0700206 1;
Ed Tanous04a258f2018-10-15 08:00:41 -0700207 procSummary["Status"]
208 ["State"] =
209 "Enabled";
210 procSummary["Model"] =
211 *value;
Ed Tanous6c34de42018-08-29 13:37:36 -0700212 }
213 }
214 }
215 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700216 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700217 "org.freedesktop.DBus.Properties", "GetAll",
218 "xyz.openbmc_project.Inventory.Item.Cpu");
219 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700220 else if (interfaceName ==
221 "xyz.openbmc_project.Common.UUID")
Ed Tanous6c34de42018-08-29 13:37:36 -0700222 {
223 BMCWEB_LOG_DEBUG
Ed Tanous04a258f2018-10-15 08:00:41 -0700224 << "Found UUID, now get its properties.";
Ed Tanous6c34de42018-08-29 13:37:36 -0700225 crow::connections::systemBus->async_method_call(
226 [aResp](
227 const boost::system::error_code ec,
228 const std::vector<
229 std::pair<std::string, VariantType>>
230 &properties) {
231 if (ec)
232 {
233 BMCWEB_LOG_DEBUG
234 << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700235 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700236 return;
237 }
238 BMCWEB_LOG_DEBUG << "Got "
239 << properties.size()
240 << "UUID properties.";
241 for (const std::pair<std::string,
Ed Tanous04a258f2018-10-15 08:00:41 -0700242 VariantType>
243 &property : properties)
Ed Tanous6c34de42018-08-29 13:37:36 -0700244 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700245 if (property.first == "BIOSVer")
Ed Tanous6c34de42018-08-29 13:37:36 -0700246 {
247 const std::string *value =
248 mapbox::getPtr<
249 const std::string>(
Ed Tanous04a258f2018-10-15 08:00:41 -0700250 property.second);
Ed Tanous6c34de42018-08-29 13:37:36 -0700251 if (value != nullptr)
252 {
253 aResp->res.jsonValue
254 ["BiosVersion"] =
255 *value;
256 }
257 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700258 if (property.first == "UUID")
Ed Tanous6c34de42018-08-29 13:37:36 -0700259 {
260 const std::string *value =
261 mapbox::getPtr<
262 const std::string>(
Ed Tanous04a258f2018-10-15 08:00:41 -0700263 property.second);
264
Ed Tanous6c34de42018-08-29 13:37:36 -0700265 if (value != nullptr)
266 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700267 std::string valueStr =
268 *value;
269 if (valueStr.size() == 32)
Ed Tanous6c34de42018-08-29 13:37:36 -0700270 {
Ed Tanous04a258f2018-10-15 08:00:41 -0700271 valueStr.insert(8, 1,
272 '-');
273 valueStr.insert(13, 1,
274 '-');
275 valueStr.insert(18, 1,
276 '-');
277 valueStr.insert(23, 1,
278 '-');
Ed Tanous6c34de42018-08-29 13:37:36 -0700279 }
Ed Tanous04a258f2018-10-15 08:00:41 -0700280 BMCWEB_LOG_DEBUG
281 << "UUID = "
282 << valueStr;
283 aResp->res
284 .jsonValue["UUID"] =
285 valueStr;
Ed Tanous6c34de42018-08-29 13:37:36 -0700286 }
287 }
288 }
289 },
Ed Tanous04a258f2018-10-15 08:00:41 -0700290 connection.first, path,
Ed Tanous6c34de42018-08-29 13:37:36 -0700291 "org.freedesktop.DBus.Properties", "GetAll",
292 "xyz.openbmc_project.Common.UUID");
293 }
294 }
295 }
296 }
297 }
298 if (foundName == false)
299 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700300 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700301 }
302 },
303 "xyz.openbmc_project.ObjectMapper",
304 "/xyz/openbmc_project/object_mapper",
305 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous66173382018-08-15 18:20:59 -0700306 "/xyz/openbmc_project/inventory", int32_t(0),
307 std::array<const char *, 5>{
308 "xyz.openbmc_project.Inventory.Decorator.Asset",
309 "xyz.openbmc_project.Inventory.Item.Cpu",
310 "xyz.openbmc_project.Inventory.Item.Dimm",
311 "xyz.openbmc_project.Inventory.Item.System",
312 "xyz.openbmc_project.Common.UUID",
313 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700314}
315
316/**
317 * @brief Retrieves identify led group properties over dbus
318 *
319 * @param[in] aResp Shared pointer for completing asynchronous calls.
320 * @param[in] callback Callback for process retrieved data.
321 *
322 * @return None.
323 */
324template <typename CallbackFunc>
325void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
326 CallbackFunc &&callback)
327{
328 BMCWEB_LOG_DEBUG << "Get led groups";
329 crow::connections::systemBus->async_method_call(
330 [aResp{std::move(aResp)},
Ed Tanous66173382018-08-15 18:20:59 -0700331 callback{std::move(callback)}](const boost::system::error_code &ec,
332 const ManagedObjectsType &resp) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700333 if (ec)
334 {
335 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700336 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700337 return;
338 }
339 BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
340 for (const auto &objPath : resp)
341 {
342 const std::string &path = objPath.first;
343 if (path.rfind("enclosure_identify") != std::string::npos)
344 {
345 for (const auto &interface : objPath.second)
346 {
347 if (interface.first == "xyz.openbmc_project.Led.Group")
348 {
349 for (const auto &property : interface.second)
350 {
351 if (property.first == "Asserted")
352 {
353 const bool *asserted =
354 mapbox::getPtr<const bool>(
355 property.second);
356 if (nullptr != asserted)
357 {
358 callback(*asserted, aResp);
359 }
360 else
361 {
362 callback(false, aResp);
363 }
364 }
365 }
366 }
367 }
368 }
369 }
370 },
371 "xyz.openbmc_project.LED.GroupManager",
372 "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
373 "GetManagedObjects");
374}
375
376template <typename CallbackFunc>
377void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
378{
379 BMCWEB_LOG_DEBUG << "Get identify led properties";
380 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700381 [aResp,
382 callback{std::move(callback)}](const boost::system::error_code ec,
383 const PropertiesType &properties) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700384 if (ec)
385 {
386 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700387 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700388 return;
389 }
390 BMCWEB_LOG_DEBUG << "Got " << properties.size()
391 << "led properties.";
392 std::string output;
393 for (const auto &property : properties)
394 {
395 if (property.first == "State")
396 {
397 const std::string *s =
398 mapbox::getPtr<std::string>(property.second);
399 if (nullptr != s)
400 {
401 BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
402 const auto pos = s->rfind('.');
403 if (pos != std::string::npos)
404 {
405 auto led = s->substr(pos + 1);
406 for (const std::pair<const char *, const char *>
407 &p :
408 std::array<
409 std::pair<const char *, const char *>, 3>{
410 {{"On", "Lit"},
411 {"Blink", "Blinking"},
412 {"Off", "Off"}}})
413 {
414 if (led == p.first)
415 {
416 output = p.second;
417 }
418 }
419 }
420 }
421 }
422 }
423 callback(output, aResp);
424 },
425 "xyz.openbmc_project.LED.Controller.identify",
426 "/xyz/openbmc_project/led/physical/identify",
427 "org.freedesktop.DBus.Properties", "GetAll",
428 "xyz.openbmc_project.Led.Physical");
429}
430
431/**
432 * @brief Retrieves host state properties over dbus
433 *
434 * @param[in] aResp Shared pointer for completing asynchronous calls.
435 *
436 * @return None.
437 */
438void getHostState(std::shared_ptr<AsyncResp> aResp)
439{
440 BMCWEB_LOG_DEBUG << "Get host information.";
441 crow::connections::systemBus->async_method_call(
Ed Tanous66173382018-08-15 18:20:59 -0700442 [aResp{std::move(aResp)}](
443 const boost::system::error_code ec,
444 const sdbusplus::message::variant<std::string> &hostState) {
Ed Tanous6c34de42018-08-29 13:37:36 -0700445 if (ec)
446 {
447 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700448 messages::internalError(aResp->res);
Ed Tanous6c34de42018-08-29 13:37:36 -0700449 return;
450 }
Ed Tanous66173382018-08-15 18:20:59 -0700451
452 const std::string *s = mapbox::getPtr<const std::string>(hostState);
453 BMCWEB_LOG_DEBUG << "Host state: " << *s;
454 if (s != nullptr)
Ed Tanous6c34de42018-08-29 13:37:36 -0700455 {
Ed Tanous66173382018-08-15 18:20:59 -0700456 // Verify Host State
457 if (*s == "xyz.openbmc_project.State.Host.Running")
Ed Tanous6c34de42018-08-29 13:37:36 -0700458 {
Ed Tanous66173382018-08-15 18:20:59 -0700459 aResp->res.jsonValue["PowerState"] = "On";
460 aResp->res.jsonValue["Status"]["State"] = "Enabled";
461 }
462 else
463 {
464 aResp->res.jsonValue["PowerState"] = "Off";
465 aResp->res.jsonValue["Status"]["State"] = "Disabled";
Ed Tanous6c34de42018-08-29 13:37:36 -0700466 }
467 }
468 },
469 "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
Ed Tanous66173382018-08-15 18:20:59 -0700470 "org.freedesktop.DBus.Properties", "Get",
471 "xyz.openbmc_project.State.Host", "CurrentHostState");
Ed Tanous6c34de42018-08-29 13:37:36 -0700472}
473
474/**
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200475 * SystemsCollection derived class for delivering ComputerSystems Collection
476 * Schema
477 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700478class SystemsCollection : public Node
479{
480 public:
481 SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
482 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700483 entityPrivileges = {
484 {boost::beast::http::verb::get, {{"Login"}}},
485 {boost::beast::http::verb::head, {{"Login"}}},
486 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
487 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
488 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
489 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
490 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200491
Ed Tanous1abe55e2018-09-05 08:30:59 -0700492 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700493 void doGet(crow::Response &res, const crow::Request &req,
494 const std::vector<std::string> &params) override
495 {
Ed Tanous66173382018-08-15 18:20:59 -0700496 BMCWEB_LOG_DEBUG << "Get list of available boards.";
497 std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous0f74e642018-11-12 15:17:05 -0800498 res.jsonValue["@odata.type"] =
499 "#ComputerSystemCollection.ComputerSystemCollection";
500 res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
501 res.jsonValue["@odata.context"] =
502 "/redfish/v1/"
503 "$metadata#ComputerSystemCollection.ComputerSystemCollection";
504 res.jsonValue["Name"] = "Computer System Collection";
Ed Tanous66173382018-08-15 18:20:59 -0700505 crow::connections::systemBus->async_method_call(
506 [asyncResp](const boost::system::error_code ec,
507 const std::vector<std::string> &resp) {
508 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700509 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700510 messages::internalError(asyncResp->res);
Ed Tanous66173382018-08-15 18:20:59 -0700511 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700512 }
Ed Tanous66173382018-08-15 18:20:59 -0700513 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
514
515 // ... prepare json array with appropriate @odata.id links
516 nlohmann::json &boardArray =
517 asyncResp->res.jsonValue["Members"];
518 boardArray = nlohmann::json::array();
519
520 // Iterate over all retrieved ObjectPaths.
521 for (const std::string &objpath : resp)
522 {
523 std::size_t lastPos = objpath.rfind("/");
524 if (lastPos != std::string::npos)
525 {
526 boardArray.push_back(
527 {{"@odata.id", "/redfish/v1/Systems/" +
528 objpath.substr(lastPos + 1)}});
529 }
530 }
531
532 asyncResp->res.jsonValue["Members@odata.count"] =
533 boardArray.size();
534 },
535 "xyz.openbmc_project.ObjectMapper",
536 "/xyz/openbmc_project/object_mapper",
537 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
538 "/xyz/openbmc_project/inventory", int32_t(0),
539 std::array<const char *, 1>{
540 "xyz.openbmc_project.Inventory.Item.Board"});
Ed Tanous1abe55e2018-09-05 08:30:59 -0700541 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200542};
543
544/**
Ed Tanouscc340dd2018-08-29 13:43:38 -0700545 * SystemActionsReset class supports handle POST method for Reset action.
546 * The class retrieves and sends data directly to D-Bus.
547 */
548class SystemActionsReset : public Node
549{
550 public:
551 SystemActionsReset(CrowApp &app) :
552 Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
553 std::string())
554 {
555 entityPrivileges = {
556 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
557 }
558
559 private:
560 /**
561 * Function handles POST method request.
562 * Analyzes POST body message before sends Reset request data to D-Bus.
563 */
564 void doPost(crow::Response &res, const crow::Request &req,
565 const std::vector<std::string> &params) override
566 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700567 auto asyncResp = std::make_shared<AsyncResp>(res);
568
569 std::string resetType;
570 if (!json_util::readJson(req, res, "ResetType", resetType))
Ed Tanouscc340dd2018-08-29 13:43:38 -0700571 {
572 return;
573 }
574
Ed Tanous9712f8a2018-09-21 13:38:49 -0700575 if (resetType == "ForceOff")
Ed Tanouscc340dd2018-08-29 13:43:38 -0700576 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700577 // Force off acts on the chassis
578 crow::connections::systemBus->async_method_call(
579 [asyncResp](const boost::system::error_code ec) {
580 if (ec)
581 {
582 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700583 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700584 return;
585 }
586 // TODO Consider support polling mechanism to verify
587 // status of host and chassis after execute the
588 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700589 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700590 },
591 "xyz.openbmc_project.State.Chassis",
592 "/xyz/openbmc_project/state/chassis0",
593 "org.freedesktop.DBus.Properties", "Set",
594 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
595 sdbusplus::message::variant<std::string>{
596 "xyz.openbmc_project.State.Chassis.Transition.Off"});
597 return;
Ed Tanouscc340dd2018-08-29 13:43:38 -0700598 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700599 // all other actions operate on the host
600 std::string command;
601 // Execute Reset Action regarding to each reset type.
602 if (resetType == "On")
603 {
604 command = "xyz.openbmc_project.State.Host.Transition.On";
605 }
606 else if (resetType == "GracefulShutdown")
607 {
608 command = "xyz.openbmc_project.State.Host.Transition.Off";
609 }
610 else if (resetType == "GracefulRestart")
611 {
612 command = "xyz.openbmc_project.State.Host.Transition.Reboot";
613 }
614 else
615 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700616 messages::actionParameterUnknown(res, "Reset", resetType);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700617 return;
618 }
619
620 crow::connections::systemBus->async_method_call(
621 [asyncResp](const boost::system::error_code ec) {
622 if (ec)
623 {
624 BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700625 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700626 return;
627 }
628 // TODO Consider support polling mechanism to verify
629 // status of host and chassis after execute the
630 // requested action.
Jason M. Billsf12894f2018-10-09 12:45:45 -0700631 messages::success(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700632 },
633 "xyz.openbmc_project.State.Host",
634 "/xyz/openbmc_project/state/host0",
635 "org.freedesktop.DBus.Properties", "Set",
636 "xyz.openbmc_project.State.Host", "RequestedHostTransition",
637 sdbusplus::message::variant<std::string>{command});
Ed Tanouscc340dd2018-08-29 13:43:38 -0700638 }
639};
640
641/**
Ed Tanous66173382018-08-15 18:20:59 -0700642 * Systems derived class for delivering Computer Systems Schema.
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200643 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700644class Systems : public Node
645{
646 public:
647 /*
648 * Default Constructor
649 */
650 Systems(CrowApp &app) :
651 Node(app, "/redfish/v1/Systems/<str>/", std::string())
652 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700653 entityPrivileges = {
654 {boost::beast::http::verb::get, {{"Login"}}},
655 {boost::beast::http::verb::head, {{"Login"}}},
656 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
657 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
658 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
659 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200660 }
661
Ed Tanous1abe55e2018-09-05 08:30:59 -0700662 private:
Ed Tanous1abe55e2018-09-05 08:30:59 -0700663 /**
664 * Functions triggers appropriate requests on DBus
665 */
666 void doGet(crow::Response &res, const crow::Request &req,
667 const std::vector<std::string> &params) override
668 {
669 // Check if there is required param, truly entering this shall be
670 // impossible
671 if (params.size() != 1)
672 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700673 messages::internalError(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700674 res.end();
675 return;
676 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200677
Ed Tanous1abe55e2018-09-05 08:30:59 -0700678 const std::string &name = params[0];
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200679
Ed Tanous0f74e642018-11-12 15:17:05 -0800680 res.jsonValue["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
681 res.jsonValue["@odata.context"] =
682 "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
683 res.jsonValue["SystemType"] = "Physical";
684 res.jsonValue["Description"] = "Computer System";
685 res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
686 "Disabled"; // TODO(Dawid), get real boot data
687 res.jsonValue["Boot"]["BootSourceOverrideTarget"] =
688 "None"; // TODO(Dawid), get real boot data
689 res.jsonValue["Boot"]["BootSourceOverrideMode"] =
690 "Legacy"; // TODO(Dawid), get real boot data
691 res.jsonValue["Boot"]
692 ["BootSourceOverrideTarget@Redfish.AllowableValues"] = {
693 "None", "Pxe", "Hdd", "Cd",
694 "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
695 // data
696 res.jsonValue["ProcessorSummary"]["Count"] = 0;
697 res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
698 res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
699 res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
Ed Tanous04a258f2018-10-15 08:00:41 -0700700 res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
701
Rapkiewicz, Pawel443c2932018-10-22 15:08:49 +0200702 res.jsonValue["Processors"] = {
703 {"@odata.id", "/redfish/v1/Systems/" + name + "/Processors"}};
704 res.jsonValue["Memory"] = {
705 {"@odata.id", "/redfish/v1/Systems/" + name + "/Memory"}};
Ed Tanouscc340dd2018-08-29 13:43:38 -0700706 // TODO Need to support ForceRestart.
707 res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
708 {"target",
709 "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
710 {"ResetType@Redfish.AllowableValues",
711 {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200712
Jason M. Billsc4bf6372018-11-05 13:48:27 -0800713 res.jsonValue["LogServices"] = {
714 {"@odata.id", "/redfish/v1/Systems/" + name + "/LogServices"}};
715
Ed Tanousa0803ef2018-08-29 13:29:23 -0700716 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700717
Ed Tanous6c34de42018-08-29 13:37:36 -0700718 getLedGroupIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700719 asyncResp,
720 [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700721 if (asserted)
722 {
723 // If led group is asserted, then another call is needed to
724 // get led status
Ed Tanous6c34de42018-08-29 13:37:36 -0700725 getLedIdentify(
Ed Tanousa0803ef2018-08-29 13:29:23 -0700726 aResp, [](const std::string &ledStatus,
727 const std::shared_ptr<AsyncResp> &aResp) {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700728 if (!ledStatus.empty())
729 {
730 aResp->res.jsonValue["IndicatorLED"] =
731 ledStatus;
732 }
733 });
734 }
735 else
736 {
737 aResp->res.jsonValue["IndicatorLED"] = "Off";
738 }
739 });
Ed Tanous6c34de42018-08-29 13:37:36 -0700740 getComputerSystem(asyncResp, name);
741 getHostState(asyncResp);
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200742 }
743
Ed Tanous1abe55e2018-09-05 08:30:59 -0700744 void doPatch(crow::Response &res, const crow::Request &req,
745 const std::vector<std::string> &params) override
746 {
747 // Check if there is required param, truly entering this shall be
748 // impossible
Ed Tanous66173382018-08-15 18:20:59 -0700749 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700750 if (params.size() != 1)
751 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700752 messages::internalError(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700753 return;
754 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700755
Ed Tanous66173382018-08-15 18:20:59 -0700756 const std::string &name = params[0];
757
Ed Tanous0f74e642018-11-12 15:17:05 -0800758 messages::success(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700759
Ed Tanous9712f8a2018-09-21 13:38:49 -0700760 std::string indicatorLedTemp;
761 boost::optional<std::string> indicatorLed = indicatorLedTemp;
762 if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
Ed Tanous66173382018-08-15 18:20:59 -0700763 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700764 return;
765 }
766
767 if (indicatorLed)
768 {
769 std::string dbusLedState;
770 if (*indicatorLed == "On")
Ed Tanous66173382018-08-15 18:20:59 -0700771 {
Ed Tanous9712f8a2018-09-21 13:38:49 -0700772 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
773 }
774 else if (*indicatorLed == "Blink")
775 {
776 dbusLedState =
777 "xyz.openbmc_project.Led.Physical.Action.Blinking";
778 }
779 else if (*indicatorLed == "Off")
780 {
781 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
Ed Tanous66173382018-08-15 18:20:59 -0700782 }
783 else
784 {
Jason M. Billsa08b46c2018-11-06 15:01:08 -0800785 messages::propertyValueNotInList(res, *indicatorLed,
786 "IndicatorLED");
Ed Tanous66173382018-08-15 18:20:59 -0700787 return;
788 }
Ed Tanous9712f8a2018-09-21 13:38:49 -0700789
790 getHostState(asyncResp);
791 getComputerSystem(asyncResp, name);
792
793 // Update led group
794 BMCWEB_LOG_DEBUG << "Update led group.";
795 crow::connections::systemBus->async_method_call(
796 [asyncResp{std::move(asyncResp)}](
797 const boost::system::error_code ec) {
798 if (ec)
799 {
800 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700801 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700802 return;
803 }
804 BMCWEB_LOG_DEBUG << "Led group update done.";
805 },
806 "xyz.openbmc_project.LED.GroupManager",
807 "/xyz/openbmc_project/led/groups/enclosure_identify",
808 "org.freedesktop.DBus.Properties", "Set",
809 "xyz.openbmc_project.Led.Group", "Asserted",
810 sdbusplus::message::variant<bool>(
811 (dbusLedState ==
812 "xyz.openbmc_project.Led.Physical.Action.Off"
813 ? false
814 : true)));
815 // Update identify led status
816 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
817 crow::connections::systemBus->async_method_call(
818 [asyncResp{std::move(asyncResp)},
819 indicatorLed{std::move(*indicatorLed)}](
820 const boost::system::error_code ec) {
821 if (ec)
822 {
823 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
Jason M. Billsf12894f2018-10-09 12:45:45 -0700824 messages::internalError(asyncResp->res);
Ed Tanous9712f8a2018-09-21 13:38:49 -0700825 return;
826 }
827 BMCWEB_LOG_DEBUG << "Led state update done.";
Ed Tanous9712f8a2018-09-21 13:38:49 -0700828 },
829 "xyz.openbmc_project.LED.Controller.identify",
830 "/xyz/openbmc_project/led/physical/identify",
831 "org.freedesktop.DBus.Properties", "Set",
832 "xyz.openbmc_project.Led.Physical", "State",
833 sdbusplus::message::variant<std::string>(dbusLedState));
Ed Tanous1abe55e2018-09-05 08:30:59 -0700834 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200835 }
Lewanczyk, Dawidc5b2abe2018-05-30 16:59:42 +0200836};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700837} // namespace redfish