xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 04a258f40c26565b4042a32b5c9b5f2414dae0df)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
181abe55efSEd Tanous #include "boost/container/flat_map.hpp"
191abe55efSEd Tanous #include "node.hpp"
201abe55efSEd Tanous 
21c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
22c5b2abe0SLewanczyk, Dawid 
231abe55efSEd Tanous namespace redfish
241abe55efSEd Tanous {
25c5b2abe0SLewanczyk, Dawid 
26c5b2abe0SLewanczyk, Dawid /**
27c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
28c5b2abe0SLewanczyk, Dawid  *
29c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
30c5b2abe0SLewanczyk, Dawid  * @param[in] name  Computer system name from request
31c5b2abe0SLewanczyk, Dawid  *
32c5b2abe0SLewanczyk, Dawid  * @return None.
33c5b2abe0SLewanczyk, Dawid  */
34a0803efaSEd Tanous void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
351abe55efSEd Tanous                        const std::string &name)
361abe55efSEd Tanous {
3755c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
3855c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
39c5b2abe0SLewanczyk, Dawid         [name, aResp{std::move(aResp)}](
40c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
41c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
426c34de48SEd Tanous                 std::string,
436c34de48SEd Tanous                 std::vector<std::pair<std::string, std::vector<std::string>>>>>
44c5b2abe0SLewanczyk, Dawid                 &subtree) {
451abe55efSEd Tanous             if (ec)
461abe55efSEd Tanous             {
4755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
48a0803efaSEd Tanous                 aResp->res.result(
49a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
50c5b2abe0SLewanczyk, Dawid                 return;
51c5b2abe0SLewanczyk, Dawid             }
52c5b2abe0SLewanczyk, Dawid             bool foundName = false;
53c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
546c34de48SEd Tanous             for (const std::pair<std::string,
556c34de48SEd Tanous                                  std::vector<std::pair<
566c34de48SEd Tanous                                      std::string, std::vector<std::string>>>>
571abe55efSEd Tanous                      &object : subtree)
581abe55efSEd Tanous             {
59c5b2abe0SLewanczyk, Dawid                 const std::string &path = object.first;
6055c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
611abe55efSEd Tanous                 const std::vector<
621abe55efSEd Tanous                     std::pair<std::string, std::vector<std::string>>>
63c5b2abe0SLewanczyk, Dawid                     &connectionNames = object.second;
641abe55efSEd Tanous                 if (connectionNames.size() < 1)
651abe55efSEd Tanous                 {
66c5b2abe0SLewanczyk, Dawid                     continue;
67c5b2abe0SLewanczyk, Dawid                 }
68c5b2abe0SLewanczyk, Dawid                 // Check if computer system exist
691abe55efSEd Tanous                 if (boost::ends_with(path, name))
701abe55efSEd Tanous                 {
71c5b2abe0SLewanczyk, Dawid                     foundName = true;
7255c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Found name: " << name;
736c34de48SEd Tanous                     const std::string connectionName = connectionNames[0].first;
7455c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
75c5b2abe0SLewanczyk, Dawid                         [aResp, name(std::string(name))](
76c5b2abe0SLewanczyk, Dawid                             const boost::system::error_code ec,
776c34de48SEd Tanous                             const std::vector<std::pair<
786c34de48SEd Tanous                                 std::string, VariantType>> &propertiesList) {
791abe55efSEd Tanous                             if (ec)
801abe55efSEd Tanous                             {
811abe55efSEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error: "
821abe55efSEd Tanous                                                  << ec;
836c34de48SEd Tanous                                 aResp->res.result(boost::beast::http::status::
84a0803efaSEd Tanous                                                       internal_server_error);
85c5b2abe0SLewanczyk, Dawid                                 return;
86c5b2abe0SLewanczyk, Dawid                             }
876c34de48SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
88c5b2abe0SLewanczyk, Dawid                                              << "properties for system";
891abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
901abe55efSEd Tanous                                      &property : propertiesList)
911abe55efSEd Tanous                             {
92c5b2abe0SLewanczyk, Dawid                                 const std::string *value =
931abe55efSEd Tanous                                     mapbox::getPtr<const std::string>(
941abe55efSEd Tanous                                         property.second);
951abe55efSEd Tanous                                 if (value != nullptr)
961abe55efSEd Tanous                                 {
971abe55efSEd Tanous                                     aResp->res.jsonValue[property.first] =
981abe55efSEd Tanous                                         *value;
99c5b2abe0SLewanczyk, Dawid                                 }
100c5b2abe0SLewanczyk, Dawid                             }
10155c7b7a2SEd Tanous                             aResp->res.jsonValue["Name"] = name;
10255c7b7a2SEd Tanous                             aResp->res.jsonValue["Id"] =
10355c7b7a2SEd Tanous                                 aResp->res.jsonValue["SerialNumber"];
104c5b2abe0SLewanczyk, Dawid                         },
1056c34de48SEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
1066c34de48SEd Tanous                         "GetAll",
1071abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
1081abe55efSEd Tanous                 }
1091abe55efSEd Tanous                 else
1101abe55efSEd Tanous                 {
1116c34de48SEd Tanous                     // This is not system, so check if it's cpu, dimm, UUID or
1126c34de48SEd Tanous                     // BiosVer
113*04a258f4SEd Tanous                     for (const auto &connection : connectionNames)
1141abe55efSEd Tanous                     {
115*04a258f4SEd Tanous                         for (const auto &interfaceName : connection.second)
1161abe55efSEd Tanous                         {
117*04a258f4SEd Tanous                             if (interfaceName ==
118*04a258f4SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm")
1191abe55efSEd Tanous                             {
1201abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
121*04a258f4SEd Tanous                                     << "Found Dimm, now get its properties.";
12255c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
1236617338dSEd Tanous                                     [aResp](
1241abe55efSEd Tanous                                         const boost::system::error_code ec,
1256c34de48SEd Tanous                                         const std::vector<
1266c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
1271abe55efSEd Tanous                                             &properties) {
1281abe55efSEd Tanous                                         if (ec)
1291abe55efSEd Tanous                                         {
1301abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
1316c34de48SEd Tanous                                                 << "DBUS response error " << ec;
132a0803efaSEd Tanous                                             aResp->res.result(
133a0803efaSEd Tanous                                                 boost::beast::http::status::
134a0803efaSEd Tanous                                                     internal_server_error);
135c5b2abe0SLewanczyk, Dawid                                             return;
136c5b2abe0SLewanczyk, Dawid                                         }
1376c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
1386c34de48SEd Tanous                                                          << properties.size()
139c5b2abe0SLewanczyk, Dawid                                                          << "Dimm properties.";
140*04a258f4SEd Tanous                                         for (const std::pair<std::string,
141*04a258f4SEd Tanous                                                              VariantType>
142*04a258f4SEd Tanous                                                  &property : properties)
1431abe55efSEd Tanous                                         {
144*04a258f4SEd Tanous                                             if (property.first ==
145*04a258f4SEd Tanous                                                 "MemorySizeInKb")
1461abe55efSEd Tanous                                             {
147*04a258f4SEd Tanous                                                 const uint64_t *value =
1481abe55efSEd Tanous                                                     mapbox::getPtr<
149*04a258f4SEd Tanous                                                         const uint64_t>(
150*04a258f4SEd Tanous                                                         property.second);
151*04a258f4SEd Tanous                                                 if (value != nullptr)
1521abe55efSEd Tanous                                                 {
1531abe55efSEd Tanous                                                     aResp->res.jsonValue
1546c34de48SEd Tanous                                                         ["TotalSystemMemoryGi"
1556c34de48SEd Tanous                                                          "B"] +=
156*04a258f4SEd Tanous                                                         *value / (1024 * 1024);
1571abe55efSEd Tanous                                                     aResp->res.jsonValue
1581abe55efSEd Tanous                                                         ["MemorySummary"]
1596c34de48SEd Tanous                                                         ["Status"]["State"] =
1601abe55efSEd Tanous                                                         "Enabled";
161c5b2abe0SLewanczyk, Dawid                                                 }
162c5b2abe0SLewanczyk, Dawid                                             }
163c5b2abe0SLewanczyk, Dawid                                         }
164c5b2abe0SLewanczyk, Dawid                                     },
165*04a258f4SEd Tanous                                     connection.first, path,
1666c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
1676c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Dimm");
1681abe55efSEd Tanous                             }
169*04a258f4SEd Tanous                             else if (interfaceName ==
170*04a258f4SEd Tanous                                      "xyz.openbmc_project.Inventory.Item.Cpu")
1711abe55efSEd Tanous                             {
1721abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
173*04a258f4SEd Tanous                                     << "Found Cpu, now get its properties.";
174a0803efaSEd Tanous                                 crow::connections::systemBus->async_method_call(
1756617338dSEd Tanous                                     [aResp](
176a0803efaSEd Tanous                                         const boost::system::error_code ec,
1776c34de48SEd Tanous                                         const std::vector<
1786c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
1791abe55efSEd Tanous                                             &properties) {
1801abe55efSEd Tanous                                         if (ec)
1811abe55efSEd Tanous                                         {
1821abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
1836c34de48SEd Tanous                                                 << "DBUS response error " << ec;
184a0803efaSEd Tanous                                             aResp->res.result(
185a0803efaSEd Tanous                                                 boost::beast::http::status::
186a0803efaSEd Tanous                                                     internal_server_error);
187c5b2abe0SLewanczyk, Dawid                                             return;
188c5b2abe0SLewanczyk, Dawid                                         }
1896c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
1906c34de48SEd Tanous                                                          << properties.size()
191c5b2abe0SLewanczyk, Dawid                                                          << "Cpu properties.";
192*04a258f4SEd Tanous                                         for (const auto &property : properties)
1931abe55efSEd Tanous                                         {
194*04a258f4SEd Tanous                                             if (property.first ==
195*04a258f4SEd Tanous                                                 "ProcessorFamily")
1961abe55efSEd Tanous                                             {
197a0803efaSEd Tanous                                                 const std::string *value =
1981abe55efSEd Tanous                                                     mapbox::getPtr<
199a0803efaSEd Tanous                                                         const std::string>(
200*04a258f4SEd Tanous                                                         property.second);
2011abe55efSEd Tanous                                                 if (value != nullptr)
2021abe55efSEd Tanous                                                 {
203*04a258f4SEd Tanous                                                     nlohmann::json
204*04a258f4SEd Tanous                                                         &procSummary =
2051abe55efSEd Tanous                                                             aResp->res.jsonValue
2066c34de48SEd Tanous                                                                 ["ProcessorSumm"
207*04a258f4SEd Tanous                                                                  "ary"];
208*04a258f4SEd Tanous                                                     nlohmann::json &procCount =
209*04a258f4SEd Tanous                                                         procSummary["Count"];
210*04a258f4SEd Tanous 
211*04a258f4SEd Tanous                                                     procCount =
212*04a258f4SEd Tanous                                                         procCount.get<int>() +
213c5b2abe0SLewanczyk, Dawid                                                         1;
214*04a258f4SEd Tanous                                                     procSummary["Status"]
215*04a258f4SEd Tanous                                                                ["State"] =
216c5b2abe0SLewanczyk, Dawid                                                                    "Enabled";
217*04a258f4SEd Tanous                                                     procSummary["Model"] =
218*04a258f4SEd Tanous                                                         *value;
219c5b2abe0SLewanczyk, Dawid                                                 }
220c5b2abe0SLewanczyk, Dawid                                             }
221c5b2abe0SLewanczyk, Dawid                                         }
222c5b2abe0SLewanczyk, Dawid                                     },
223*04a258f4SEd Tanous                                     connection.first, path,
2246c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
2256c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Cpu");
2261abe55efSEd Tanous                             }
227*04a258f4SEd Tanous                             else if (interfaceName ==
228*04a258f4SEd Tanous                                      "xyz.openbmc_project.Common.UUID")
2291abe55efSEd Tanous                             {
2301abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
231*04a258f4SEd Tanous                                     << "Found UUID, now get its properties.";
23255c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
2331abe55efSEd Tanous                                     [aResp](
2341abe55efSEd Tanous                                         const boost::system::error_code ec,
2356c34de48SEd Tanous                                         const std::vector<
2366c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
2371abe55efSEd Tanous                                             &properties) {
2381abe55efSEd Tanous                                         if (ec)
2391abe55efSEd Tanous                                         {
2401abe55efSEd Tanous                                             BMCWEB_LOG_DEBUG
2416c34de48SEd Tanous                                                 << "DBUS response error " << ec;
242a0803efaSEd Tanous                                             aResp->res.result(
243a0803efaSEd Tanous                                                 boost::beast::http::status::
244a0803efaSEd Tanous                                                     internal_server_error);
245c5b2abe0SLewanczyk, Dawid                                             return;
246c5b2abe0SLewanczyk, Dawid                                         }
2476c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
2486c34de48SEd Tanous                                                          << properties.size()
249c5b2abe0SLewanczyk, Dawid                                                          << "UUID properties.";
2501abe55efSEd Tanous                                         for (const std::pair<std::string,
251*04a258f4SEd Tanous                                                              VariantType>
252*04a258f4SEd Tanous                                                  &property : properties)
2531abe55efSEd Tanous                                         {
254*04a258f4SEd Tanous                                             if (property.first == "BIOSVer")
2551abe55efSEd Tanous                                             {
256c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
2571abe55efSEd Tanous                                                     mapbox::getPtr<
2581abe55efSEd Tanous                                                         const std::string>(
259*04a258f4SEd Tanous                                                         property.second);
2601abe55efSEd Tanous                                                 if (value != nullptr)
2611abe55efSEd Tanous                                                 {
2621abe55efSEd Tanous                                                     aResp->res.jsonValue
2631abe55efSEd Tanous                                                         ["BiosVersion"] =
2641abe55efSEd Tanous                                                         *value;
265c5b2abe0SLewanczyk, Dawid                                                 }
266c5b2abe0SLewanczyk, Dawid                                             }
267*04a258f4SEd Tanous                                             if (property.first == "UUID")
2681abe55efSEd Tanous                                             {
269c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
2701abe55efSEd Tanous                                                     mapbox::getPtr<
2711abe55efSEd Tanous                                                         const std::string>(
272*04a258f4SEd Tanous                                                         property.second);
273*04a258f4SEd Tanous 
2741abe55efSEd Tanous                                                 if (value != nullptr)
2751abe55efSEd Tanous                                                 {
276*04a258f4SEd Tanous                                                     std::string valueStr =
2771abe55efSEd Tanous                                                         *value;
278*04a258f4SEd Tanous                                                     if (valueStr.size() == 32)
2791abe55efSEd Tanous                                                     {
280*04a258f4SEd Tanous                                                         valueStr.insert(8, 1,
281*04a258f4SEd Tanous                                                                         '-');
282*04a258f4SEd Tanous                                                         valueStr.insert(13, 1,
283*04a258f4SEd Tanous                                                                         '-');
284*04a258f4SEd Tanous                                                         valueStr.insert(18, 1,
285*04a258f4SEd Tanous                                                                         '-');
286*04a258f4SEd Tanous                                                         valueStr.insert(23, 1,
287*04a258f4SEd Tanous                                                                         '-');
288*04a258f4SEd Tanous                                                     }
289*04a258f4SEd Tanous                                                     BMCWEB_LOG_DEBUG
290*04a258f4SEd Tanous                                                         << "UUID = "
291*04a258f4SEd Tanous                                                         << valueStr;
2926c34de48SEd Tanous                                                     aResp->res
2936c34de48SEd Tanous                                                         .jsonValue["UUID"] =
294*04a258f4SEd Tanous                                                         valueStr;
295c5b2abe0SLewanczyk, Dawid                                                 }
296c5b2abe0SLewanczyk, Dawid                                             }
297c5b2abe0SLewanczyk, Dawid                                         }
298c5b2abe0SLewanczyk, Dawid                                     },
299*04a258f4SEd Tanous                                     connection.first, path,
3006c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
3011abe55efSEd Tanous                                     "xyz.openbmc_project.Common.UUID");
302c5b2abe0SLewanczyk, Dawid                             }
303c5b2abe0SLewanczyk, Dawid                         }
304c5b2abe0SLewanczyk, Dawid                     }
305c5b2abe0SLewanczyk, Dawid                 }
306c5b2abe0SLewanczyk, Dawid             }
3071abe55efSEd Tanous             if (foundName == false)
3081abe55efSEd Tanous             {
309a0803efaSEd Tanous                 aResp->res.result(
310a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
311c5b2abe0SLewanczyk, Dawid             }
312c5b2abe0SLewanczyk, Dawid         },
313c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
314c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
315c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
3166617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
3176617338dSEd Tanous         std::array<const char *, 5>{
3186617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
3196617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
3206617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
3216617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
3226617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
3236617338dSEd Tanous         });
324c5b2abe0SLewanczyk, Dawid }
325c5b2abe0SLewanczyk, Dawid 
326c5b2abe0SLewanczyk, Dawid /**
327c5b2abe0SLewanczyk, Dawid  * @brief Retrieves identify led group properties over dbus
328c5b2abe0SLewanczyk, Dawid  *
329c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
330c5b2abe0SLewanczyk, Dawid  * @param[in] callback  Callback for process retrieved data.
331c5b2abe0SLewanczyk, Dawid  *
332c5b2abe0SLewanczyk, Dawid  * @return None.
333c5b2abe0SLewanczyk, Dawid  */
334c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
335a0803efaSEd Tanous void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
3361abe55efSEd Tanous                          CallbackFunc &&callback)
3371abe55efSEd Tanous {
33855c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get led groups";
33955c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
3401abe55efSEd Tanous         [aResp{std::move(aResp)},
3416617338dSEd Tanous          callback{std::move(callback)}](const boost::system::error_code &ec,
3421abe55efSEd Tanous                                         const ManagedObjectsType &resp) {
3431abe55efSEd Tanous             if (ec)
3441abe55efSEd Tanous             {
34555c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
346a0803efaSEd Tanous                 aResp->res.result(
347a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
348c5b2abe0SLewanczyk, Dawid                 return;
349c5b2abe0SLewanczyk, Dawid             }
3506c34de48SEd Tanous             BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
3511abe55efSEd Tanous             for (const auto &objPath : resp)
3521abe55efSEd Tanous             {
353c5b2abe0SLewanczyk, Dawid                 const std::string &path = objPath.first;
3541abe55efSEd Tanous                 if (path.rfind("enclosure_identify") != std::string::npos)
3551abe55efSEd Tanous                 {
3561abe55efSEd Tanous                     for (const auto &interface : objPath.second)
3571abe55efSEd Tanous                     {
3586c34de48SEd Tanous                         if (interface.first == "xyz.openbmc_project.Led.Group")
3591abe55efSEd Tanous                         {
3601abe55efSEd Tanous                             for (const auto &property : interface.second)
3611abe55efSEd Tanous                             {
3621abe55efSEd Tanous                                 if (property.first == "Asserted")
3631abe55efSEd Tanous                                 {
364c5b2abe0SLewanczyk, Dawid                                     const bool *asserted =
3651abe55efSEd Tanous                                         mapbox::getPtr<const bool>(
3661abe55efSEd Tanous                                             property.second);
3671abe55efSEd Tanous                                     if (nullptr != asserted)
3681abe55efSEd Tanous                                     {
369c5b2abe0SLewanczyk, Dawid                                         callback(*asserted, aResp);
3701abe55efSEd Tanous                                     }
3711abe55efSEd Tanous                                     else
3721abe55efSEd Tanous                                     {
373c5b2abe0SLewanczyk, Dawid                                         callback(false, aResp);
374c5b2abe0SLewanczyk, Dawid                                     }
375c5b2abe0SLewanczyk, Dawid                                 }
376c5b2abe0SLewanczyk, Dawid                             }
377c5b2abe0SLewanczyk, Dawid                         }
378c5b2abe0SLewanczyk, Dawid                     }
379c5b2abe0SLewanczyk, Dawid                 }
380c5b2abe0SLewanczyk, Dawid             }
381c5b2abe0SLewanczyk, Dawid         },
382c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.GroupManager",
3836c34de48SEd Tanous         "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
3846c34de48SEd Tanous         "GetManagedObjects");
385c5b2abe0SLewanczyk, Dawid }
386c5b2abe0SLewanczyk, Dawid 
387c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
3886c34de48SEd Tanous void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
3891abe55efSEd Tanous {
39055c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get identify led properties";
39155c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
3926617338dSEd Tanous         [aResp,
3936617338dSEd Tanous          callback{std::move(callback)}](const boost::system::error_code ec,
394c5b2abe0SLewanczyk, Dawid                                         const PropertiesType &properties) {
3951abe55efSEd Tanous             if (ec)
3961abe55efSEd Tanous             {
39755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
398a0803efaSEd Tanous                 aResp->res.result(
399a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
400c5b2abe0SLewanczyk, Dawid                 return;
401c5b2abe0SLewanczyk, Dawid             }
4021abe55efSEd Tanous             BMCWEB_LOG_DEBUG << "Got " << properties.size()
4031abe55efSEd Tanous                              << "led properties.";
404c5b2abe0SLewanczyk, Dawid             std::string output;
4051abe55efSEd Tanous             for (const auto &property : properties)
4061abe55efSEd Tanous             {
4071abe55efSEd Tanous                 if (property.first == "State")
4081abe55efSEd Tanous                 {
409c5b2abe0SLewanczyk, Dawid                     const std::string *s =
41055c7b7a2SEd Tanous                         mapbox::getPtr<std::string>(property.second);
4111abe55efSEd Tanous                     if (nullptr != s)
4121abe55efSEd Tanous                     {
41355c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
414c5b2abe0SLewanczyk, Dawid                         const auto pos = s->rfind('.');
4151abe55efSEd Tanous                         if (pos != std::string::npos)
4161abe55efSEd Tanous                         {
417c5b2abe0SLewanczyk, Dawid                             auto led = s->substr(pos + 1);
4181abe55efSEd Tanous                             for (const std::pair<const char *, const char *>
4191abe55efSEd Tanous                                      &p :
4201abe55efSEd Tanous                                  std::array<
4216c34de48SEd Tanous                                      std::pair<const char *, const char *>, 3>{
4226c34de48SEd Tanous                                      {{"On", "Lit"},
423c5b2abe0SLewanczyk, Dawid                                       {"Blink", "Blinking"},
4241abe55efSEd Tanous                                       {"Off", "Off"}}})
4251abe55efSEd Tanous                             {
4261abe55efSEd Tanous                                 if (led == p.first)
4271abe55efSEd Tanous                                 {
428c5b2abe0SLewanczyk, Dawid                                     output = p.second;
429c5b2abe0SLewanczyk, Dawid                                 }
430c5b2abe0SLewanczyk, Dawid                             }
431c5b2abe0SLewanczyk, Dawid                         }
432c5b2abe0SLewanczyk, Dawid                     }
433c5b2abe0SLewanczyk, Dawid                 }
434c5b2abe0SLewanczyk, Dawid             }
435c5b2abe0SLewanczyk, Dawid             callback(output, aResp);
436c5b2abe0SLewanczyk, Dawid         },
437c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.Controller.identify",
438c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/led/physical/identify",
439c5b2abe0SLewanczyk, Dawid         "org.freedesktop.DBus.Properties", "GetAll",
440c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Led.Physical");
441c5b2abe0SLewanczyk, Dawid }
442c5b2abe0SLewanczyk, Dawid 
443c5b2abe0SLewanczyk, Dawid /**
444c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
445c5b2abe0SLewanczyk, Dawid  *
446c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
447c5b2abe0SLewanczyk, Dawid  *
448c5b2abe0SLewanczyk, Dawid  * @return None.
449c5b2abe0SLewanczyk, Dawid  */
450a0803efaSEd Tanous void getHostState(std::shared_ptr<AsyncResp> aResp)
4511abe55efSEd Tanous {
45255c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
45355c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
4546617338dSEd Tanous         [aResp{std::move(aResp)}](
4556617338dSEd Tanous             const boost::system::error_code ec,
4566617338dSEd Tanous             const sdbusplus::message::variant<std::string> &hostState) {
4571abe55efSEd Tanous             if (ec)
4581abe55efSEd Tanous             {
45955c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
460a0803efaSEd Tanous                 aResp->res.result(
461a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
462c5b2abe0SLewanczyk, Dawid                 return;
463c5b2abe0SLewanczyk, Dawid             }
4646617338dSEd Tanous 
4656617338dSEd Tanous             const std::string *s = mapbox::getPtr<const std::string>(hostState);
46655c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
4676617338dSEd Tanous             if (s != nullptr)
4681abe55efSEd Tanous             {
469c5b2abe0SLewanczyk, Dawid                 // Verify Host State
4706617338dSEd Tanous                 if (*s == "xyz.openbmc_project.State.Host.Running")
4711abe55efSEd Tanous                 {
47255c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
4736617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
4741abe55efSEd Tanous                 }
4751abe55efSEd Tanous                 else
4761abe55efSEd Tanous                 {
47755c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
4786617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
479c5b2abe0SLewanczyk, Dawid                 }
480c5b2abe0SLewanczyk, Dawid             }
481c5b2abe0SLewanczyk, Dawid         },
4826c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
4836617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
4846617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
485c5b2abe0SLewanczyk, Dawid }
486c5b2abe0SLewanczyk, Dawid 
487c5b2abe0SLewanczyk, Dawid /**
488c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
489c5b2abe0SLewanczyk, Dawid  * Schema
490c5b2abe0SLewanczyk, Dawid  */
4911abe55efSEd Tanous class SystemsCollection : public Node
4921abe55efSEd Tanous {
493c5b2abe0SLewanczyk, Dawid   public:
4941abe55efSEd Tanous     SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
4951abe55efSEd Tanous     {
496c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] =
497c5b2abe0SLewanczyk, Dawid             "#ComputerSystemCollection.ComputerSystemCollection";
498c5b2abe0SLewanczyk, Dawid         Node::json["@odata.id"] = "/redfish/v1/Systems";
499c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
500c5b2abe0SLewanczyk, Dawid             "/redfish/v1/"
501c5b2abe0SLewanczyk, Dawid             "$metadata#ComputerSystemCollection.ComputerSystemCollection";
502c5b2abe0SLewanczyk, Dawid         Node::json["Name"] = "Computer System Collection";
503c5b2abe0SLewanczyk, Dawid 
504c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
505c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
506c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
507c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
508c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
509c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
510c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
511c5b2abe0SLewanczyk, Dawid     }
512c5b2abe0SLewanczyk, Dawid 
513c5b2abe0SLewanczyk, Dawid   private:
51455c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
5151abe55efSEd Tanous                const std::vector<std::string> &params) override
5161abe55efSEd Tanous     {
5176617338dSEd Tanous         BMCWEB_LOG_DEBUG << "Get list of available boards.";
5186617338dSEd Tanous         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
5196617338dSEd Tanous         res.jsonValue = Node::json;
5206617338dSEd Tanous         crow::connections::systemBus->async_method_call(
5216617338dSEd Tanous             [asyncResp](const boost::system::error_code ec,
5226617338dSEd Tanous                         const std::vector<std::string> &resp) {
5236617338dSEd Tanous                 if (ec)
5241abe55efSEd Tanous                 {
5256617338dSEd Tanous                     asyncResp->res.result(
5266617338dSEd Tanous                         boost::beast::http::status::internal_server_error);
5276617338dSEd Tanous                     return;
5286617338dSEd Tanous                 }
5296617338dSEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
5306617338dSEd Tanous 
531c5b2abe0SLewanczyk, Dawid                 // ... prepare json array with appropriate @odata.id links
5326617338dSEd Tanous                 nlohmann::json &boardArray =
5336617338dSEd Tanous                     asyncResp->res.jsonValue["Members"];
5346617338dSEd Tanous                 boardArray = nlohmann::json::array();
5356617338dSEd Tanous 
5366617338dSEd Tanous                 // Iterate over all retrieved ObjectPaths.
5376617338dSEd Tanous                 for (const std::string &objpath : resp)
5386617338dSEd Tanous                 {
5396617338dSEd Tanous                     std::size_t lastPos = objpath.rfind("/");
5406617338dSEd Tanous                     if (lastPos != std::string::npos)
5411abe55efSEd Tanous                     {
542c5b2abe0SLewanczyk, Dawid                         boardArray.push_back(
5436617338dSEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/" +
5446617338dSEd Tanous                                                objpath.substr(lastPos + 1)}});
545c5b2abe0SLewanczyk, Dawid                     }
5461abe55efSEd Tanous                 }
5476617338dSEd Tanous 
5486617338dSEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] =
5496617338dSEd Tanous                     boardArray.size();
5506617338dSEd Tanous             },
5516617338dSEd Tanous             "xyz.openbmc_project.ObjectMapper",
5526617338dSEd Tanous             "/xyz/openbmc_project/object_mapper",
5536617338dSEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
5546617338dSEd Tanous             "/xyz/openbmc_project/inventory", int32_t(0),
5556617338dSEd Tanous             std::array<const char *, 1>{
5566617338dSEd Tanous                 "xyz.openbmc_project.Inventory.Item.Board"});
557c5b2abe0SLewanczyk, Dawid     }
558c5b2abe0SLewanczyk, Dawid };
559c5b2abe0SLewanczyk, Dawid 
560c5b2abe0SLewanczyk, Dawid /**
561cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
562cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
563cc340dd9SEd Tanous  */
564cc340dd9SEd Tanous class SystemActionsReset : public Node
565cc340dd9SEd Tanous {
566cc340dd9SEd Tanous   public:
567cc340dd9SEd Tanous     SystemActionsReset(CrowApp &app) :
568cc340dd9SEd Tanous         Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
569cc340dd9SEd Tanous              std::string())
570cc340dd9SEd Tanous     {
571cc340dd9SEd Tanous         entityPrivileges = {
572cc340dd9SEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
573cc340dd9SEd Tanous     }
574cc340dd9SEd Tanous 
575cc340dd9SEd Tanous   private:
576cc340dd9SEd Tanous     /**
577cc340dd9SEd Tanous      * Function handles POST method request.
578cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
579cc340dd9SEd Tanous      */
580cc340dd9SEd Tanous     void doPost(crow::Response &res, const crow::Request &req,
581cc340dd9SEd Tanous                 const std::vector<std::string> &params) override
582cc340dd9SEd Tanous     {
583cc340dd9SEd Tanous         // Parse JSON request body.
584cc340dd9SEd Tanous         nlohmann::json post;
585cc340dd9SEd Tanous         if (!json_util::processJsonFromRequest(res, req, post))
586cc340dd9SEd Tanous         {
587cc340dd9SEd Tanous             return;
588cc340dd9SEd Tanous         }
589cc340dd9SEd Tanous 
590cc340dd9SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
591cc340dd9SEd Tanous 
592cc340dd9SEd Tanous         for (const auto &item : post.items())
593cc340dd9SEd Tanous         {
594cc340dd9SEd Tanous             if (item.key() == "ResetType")
595cc340dd9SEd Tanous             {
596cc340dd9SEd Tanous                 const std::string *reqResetType =
597cc340dd9SEd Tanous                     item.value().get_ptr<const std::string *>();
598cc340dd9SEd Tanous                 if (reqResetType == nullptr)
599cc340dd9SEd Tanous                 {
600cc340dd9SEd Tanous                     res.result(boost::beast::http::status::bad_request);
601cc340dd9SEd Tanous                     messages::addMessageToErrorJson(
602cc340dd9SEd Tanous                         asyncResp->res.jsonValue,
603cc340dd9SEd Tanous                         messages::actionParameterValueFormatError(
604cc340dd9SEd Tanous                             item.value().dump(), "ResetType",
605cc340dd9SEd Tanous                             "ComputerSystem.Reset"));
606cc340dd9SEd Tanous                     res.end();
607cc340dd9SEd Tanous                     return;
608cc340dd9SEd Tanous                 }
609cc340dd9SEd Tanous 
610cc340dd9SEd Tanous                 if (*reqResetType == "ForceOff")
611cc340dd9SEd Tanous                 {
612cc340dd9SEd Tanous                     // Force off acts on the chassis
613cc340dd9SEd Tanous                     crow::connections::systemBus->async_method_call(
614cc340dd9SEd Tanous                         [asyncResp](const boost::system::error_code ec) {
615cc340dd9SEd Tanous                             if (ec)
616cc340dd9SEd Tanous                             {
617cc340dd9SEd Tanous                                 BMCWEB_LOG_ERROR << "D-Bus responses error: "
618cc340dd9SEd Tanous                                                  << ec;
619cc340dd9SEd Tanous                                 asyncResp->res.result(
620cc340dd9SEd Tanous                                     boost::beast::http::status::
621cc340dd9SEd Tanous                                         internal_server_error);
622cc340dd9SEd Tanous                                 return;
623cc340dd9SEd Tanous                             }
624cc340dd9SEd Tanous                             // TODO Consider support polling mechanism to verify
625cc340dd9SEd Tanous                             // status of host and chassis after execute the
626cc340dd9SEd Tanous                             // requested action.
627cc340dd9SEd Tanous                             BMCWEB_LOG_DEBUG << "Response with no content";
628cc340dd9SEd Tanous                             asyncResp->res.result(
629cc340dd9SEd Tanous                                 boost::beast::http::status::no_content);
630cc340dd9SEd Tanous                         },
631cc340dd9SEd Tanous                         "xyz.openbmc_project.State.Chassis",
632cc340dd9SEd Tanous                         "/xyz/openbmc_project/state/chassis0",
633cc340dd9SEd Tanous                         "org.freedesktop.DBus.Properties", "Set",
634cc340dd9SEd Tanous                         "RequestedPowerTransition",
635cc340dd9SEd Tanous                         "xyz.openbmc_project.State.Chassis",
636cc340dd9SEd Tanous                         sdbusplus::message::variant<std::string>{
637cc340dd9SEd Tanous                             "xyz.openbmc_project.State.Chassis.Transition."
638cc340dd9SEd Tanous                             "Off"});
639cc340dd9SEd Tanous                     return;
640cc340dd9SEd Tanous                 }
641cc340dd9SEd Tanous                 // all other actions operate on the host
642cc340dd9SEd Tanous                 std::string command;
643cc340dd9SEd Tanous                 // Execute Reset Action regarding to each reset type.
644cc340dd9SEd Tanous                 if (*reqResetType == "On")
645cc340dd9SEd Tanous                 {
646cc340dd9SEd Tanous                     command = "xyz.openbmc_project.State.Host.Transition.On";
647cc340dd9SEd Tanous                 }
648cc340dd9SEd Tanous                 else if (*reqResetType == "GracefulShutdown")
649cc340dd9SEd Tanous                 {
650cc340dd9SEd Tanous                     command = "xyz.openbmc_project.State.Host.Transition.Off";
651cc340dd9SEd Tanous                 }
652cc340dd9SEd Tanous                 else if (*reqResetType == "GracefulRestart")
653cc340dd9SEd Tanous                 {
654cc340dd9SEd Tanous                     command =
655cc340dd9SEd Tanous                         "xyz.openbmc_project.State.Host.Transition.Reboot";
656cc340dd9SEd Tanous                 }
657cc340dd9SEd Tanous                 else
658cc340dd9SEd Tanous                 {
659cc340dd9SEd Tanous                     res.result(boost::beast::http::status::bad_request);
660cc340dd9SEd Tanous                     messages::addMessageToErrorJson(
661cc340dd9SEd Tanous                         asyncResp->res.jsonValue,
662cc340dd9SEd Tanous                         messages::actionParameterUnknown("Reset",
663cc340dd9SEd Tanous                                                          *reqResetType));
664cc340dd9SEd Tanous                     res.end();
665cc340dd9SEd Tanous                     return;
666cc340dd9SEd Tanous                 }
667cc340dd9SEd Tanous 
668cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
669cc340dd9SEd Tanous                     [asyncResp](const boost::system::error_code ec) {
670cc340dd9SEd Tanous                         if (ec)
671cc340dd9SEd Tanous                         {
672cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
673cc340dd9SEd Tanous                             asyncResp->res.result(boost::beast::http::status::
674cc340dd9SEd Tanous                                                       internal_server_error);
675cc340dd9SEd Tanous                             return;
676cc340dd9SEd Tanous                         }
677cc340dd9SEd Tanous                         // TODO Consider support polling mechanism to verify
678cc340dd9SEd Tanous                         // status of host and chassis after execute the
679cc340dd9SEd Tanous                         // requested action.
680cc340dd9SEd Tanous                         BMCWEB_LOG_DEBUG << "Response with no content";
681cc340dd9SEd Tanous                         asyncResp->res.result(
682cc340dd9SEd Tanous                             boost::beast::http::status::no_content);
683cc340dd9SEd Tanous                     },
684cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
685cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
686cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
687cc340dd9SEd Tanous                     "RequestedHostTransition", "xyz.openbmc_project.State.Host",
688cc340dd9SEd Tanous                     sdbusplus::message::variant<std::string>{command});
689cc340dd9SEd Tanous             }
690cc340dd9SEd Tanous             else
691cc340dd9SEd Tanous             {
692cc340dd9SEd Tanous                 messages::addMessageToErrorJson(
693cc340dd9SEd Tanous                     asyncResp->res.jsonValue,
694cc340dd9SEd Tanous                     messages::actionParameterUnknown("ComputerSystem.Reset",
695cc340dd9SEd Tanous                                                      item.key()));
696cc340dd9SEd Tanous             }
697cc340dd9SEd Tanous         }
698cc340dd9SEd Tanous     }
699cc340dd9SEd Tanous };
700cc340dd9SEd Tanous 
701cc340dd9SEd Tanous /**
7026617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
703c5b2abe0SLewanczyk, Dawid  */
7041abe55efSEd Tanous class Systems : public Node
7051abe55efSEd Tanous {
706c5b2abe0SLewanczyk, Dawid   public:
707c5b2abe0SLewanczyk, Dawid     /*
708c5b2abe0SLewanczyk, Dawid      * Default Constructor
709c5b2abe0SLewanczyk, Dawid      */
7101abe55efSEd Tanous     Systems(CrowApp &app) :
7111abe55efSEd Tanous         Node(app, "/redfish/v1/Systems/<str>/", std::string())
7121abe55efSEd Tanous     {
713c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
714c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
715c5b2abe0SLewanczyk, Dawid             "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
716c5b2abe0SLewanczyk, Dawid         Node::json["SystemType"] = "Physical";
717c5b2abe0SLewanczyk, Dawid         Node::json["Description"] = "Computer System";
718c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideEnabled"] =
719c5b2abe0SLewanczyk, Dawid             "Disabled"; // TODO(Dawid), get real boot data
720c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideTarget"] =
721c5b2abe0SLewanczyk, Dawid             "None"; // TODO(Dawid), get real boot data
722c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideMode"] =
723c5b2abe0SLewanczyk, Dawid             "Legacy"; // TODO(Dawid), get real boot data
7241abe55efSEd Tanous         Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
7251abe55efSEd Tanous             {"None",      "Pxe",       "Hdd", "Cd",
7261abe55efSEd Tanous              "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
7271abe55efSEd Tanous                                                // data
728*04a258f4SEd Tanous         Node::json["ProcessorSummary"]["Count"] = 0;
729c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
730c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
731c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
732c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
733c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
734c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
735c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
736c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
737c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
738c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
739c5b2abe0SLewanczyk, Dawid     }
740c5b2abe0SLewanczyk, Dawid 
741c5b2abe0SLewanczyk, Dawid   private:
742c5b2abe0SLewanczyk, Dawid     /**
743c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
744c5b2abe0SLewanczyk, Dawid      */
74555c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
7461abe55efSEd Tanous                const std::vector<std::string> &params) override
7471abe55efSEd Tanous     {
748c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
749c5b2abe0SLewanczyk, Dawid         // impossible
7501abe55efSEd Tanous         if (params.size() != 1)
7511abe55efSEd Tanous         {
752c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
753c5b2abe0SLewanczyk, Dawid             res.end();
754c5b2abe0SLewanczyk, Dawid             return;
755c5b2abe0SLewanczyk, Dawid         }
756c5b2abe0SLewanczyk, Dawid 
757c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
758c5b2abe0SLewanczyk, Dawid 
759*04a258f4SEd Tanous         res.jsonValue = Node::json;
760*04a258f4SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
761*04a258f4SEd Tanous 
762cc340dd9SEd Tanous         // TODO Need to support ForceRestart.
763cc340dd9SEd Tanous         res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
764cc340dd9SEd Tanous             {"target",
765cc340dd9SEd Tanous              "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
766cc340dd9SEd Tanous             {"ResetType@Redfish.AllowableValues",
767cc340dd9SEd Tanous              {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
768c5b2abe0SLewanczyk, Dawid 
769a0803efaSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
770c5b2abe0SLewanczyk, Dawid 
7716c34de48SEd Tanous         getLedGroupIdentify(
772a0803efaSEd Tanous             asyncResp,
773a0803efaSEd Tanous             [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
7741abe55efSEd Tanous                 if (asserted)
7751abe55efSEd Tanous                 {
776c5b2abe0SLewanczyk, Dawid                     // If led group is asserted, then another call is needed to
777c5b2abe0SLewanczyk, Dawid                     // get led status
7786c34de48SEd Tanous                     getLedIdentify(
779a0803efaSEd Tanous                         aResp, [](const std::string &ledStatus,
780a0803efaSEd Tanous                                   const std::shared_ptr<AsyncResp> &aResp) {
7811abe55efSEd Tanous                             if (!ledStatus.empty())
7821abe55efSEd Tanous                             {
7831abe55efSEd Tanous                                 aResp->res.jsonValue["IndicatorLED"] =
7841abe55efSEd Tanous                                     ledStatus;
785c5b2abe0SLewanczyk, Dawid                             }
786c5b2abe0SLewanczyk, Dawid                         });
7871abe55efSEd Tanous                 }
7881abe55efSEd Tanous                 else
7891abe55efSEd Tanous                 {
79055c7b7a2SEd Tanous                     aResp->res.jsonValue["IndicatorLED"] = "Off";
791c5b2abe0SLewanczyk, Dawid                 }
792c5b2abe0SLewanczyk, Dawid             });
7936c34de48SEd Tanous         getComputerSystem(asyncResp, name);
7946c34de48SEd Tanous         getHostState(asyncResp);
795c5b2abe0SLewanczyk, Dawid     }
796c5b2abe0SLewanczyk, Dawid 
79755c7b7a2SEd Tanous     void doPatch(crow::Response &res, const crow::Request &req,
7981abe55efSEd Tanous                  const std::vector<std::string> &params) override
7991abe55efSEd Tanous     {
800c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
801c5b2abe0SLewanczyk, Dawid         // impossible
8026617338dSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
8031abe55efSEd Tanous         if (params.size() != 1)
8041abe55efSEd Tanous         {
805c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
806c5b2abe0SLewanczyk, Dawid             return;
807c5b2abe0SLewanczyk, Dawid         }
808c5b2abe0SLewanczyk, Dawid         // Parse JSON request body
809c5b2abe0SLewanczyk, Dawid         nlohmann::json patch;
8101abe55efSEd Tanous         if (!json_util::processJsonFromRequest(res, req, patch))
8111abe55efSEd Tanous         {
812c5b2abe0SLewanczyk, Dawid             return;
813c5b2abe0SLewanczyk, Dawid         }
814c5b2abe0SLewanczyk, Dawid 
8156617338dSEd Tanous         const std::string &name = params[0];
8166617338dSEd Tanous 
81755c7b7a2SEd Tanous         res.jsonValue = Node::json;
81855c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
819c5b2abe0SLewanczyk, Dawid 
8206617338dSEd Tanous         for (const auto &item : patch.items())
8216617338dSEd Tanous         {
8226617338dSEd Tanous             if (item.key() == "IndicatorLed")
8236617338dSEd Tanous             {
8246617338dSEd Tanous                 const std::string *reqLedState =
8256617338dSEd Tanous                     item.value().get_ptr<const std::string *>();
8266617338dSEd Tanous                 if (reqLedState == nullptr)
8276617338dSEd Tanous                 {
8286617338dSEd Tanous                     messages::addMessageToErrorJson(
8296617338dSEd Tanous                         asyncResp->res.jsonValue,
8306617338dSEd Tanous                         messages::propertyValueFormatError(item.value().dump(),
8316617338dSEd Tanous                                                            item.key()));
8326617338dSEd Tanous                     return;
8336617338dSEd Tanous                 }
8346617338dSEd Tanous 
8356617338dSEd Tanous                 // Verify key value
8366617338dSEd Tanous                 std::string dbusLedState;
8376617338dSEd Tanous                 if (*reqLedState == "On")
8386617338dSEd Tanous                 {
8396617338dSEd Tanous                     dbusLedState =
8406617338dSEd Tanous                         "xyz.openbmc_project.Led.Physical.Action.Lit";
8416617338dSEd Tanous                 }
8426617338dSEd Tanous                 else if (*reqLedState == "Blink")
8436617338dSEd Tanous                 {
8446617338dSEd Tanous                     dbusLedState =
8456617338dSEd Tanous                         "xyz.openbmc_project.Led.Physical.Action.Blinking";
8466617338dSEd Tanous                 }
8476617338dSEd Tanous                 else if (*reqLedState == "Off")
8486617338dSEd Tanous                 {
8496617338dSEd Tanous                     dbusLedState =
8506617338dSEd Tanous                         "xyz.openbmc_project.Led.Physical.Action.Off";
8516617338dSEd Tanous                 }
8526617338dSEd Tanous                 else
8536617338dSEd Tanous                 {
8546617338dSEd Tanous                     messages::addMessageToJsonRoot(
8556617338dSEd Tanous                         res.jsonValue, messages::propertyValueNotInList(
8566617338dSEd Tanous                                            *reqLedState, "IndicatorLED"));
8576617338dSEd Tanous                     return;
8586617338dSEd Tanous                 }
8596617338dSEd Tanous 
8606c34de48SEd Tanous                 getHostState(asyncResp);
8616c34de48SEd Tanous                 getComputerSystem(asyncResp, name);
862c5b2abe0SLewanczyk, Dawid 
863c5b2abe0SLewanczyk, Dawid                 // Update led group
86455c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Update led group.";
86555c7b7a2SEd Tanous                 crow::connections::systemBus->async_method_call(
8666617338dSEd Tanous                     [asyncResp{std::move(asyncResp)}](
867c5b2abe0SLewanczyk, Dawid                         const boost::system::error_code ec) {
8681abe55efSEd Tanous                         if (ec)
8691abe55efSEd Tanous                         {
87055c7b7a2SEd Tanous                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
8716617338dSEd Tanous                             asyncResp->res.result(boost::beast::http::status::
8726617338dSEd Tanous                                                       internal_server_error);
873c5b2abe0SLewanczyk, Dawid                             return;
874c5b2abe0SLewanczyk, Dawid                         }
87555c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Led group update done.";
876c5b2abe0SLewanczyk, Dawid                     },
877c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.LED.GroupManager",
878c5b2abe0SLewanczyk, Dawid                     "/xyz/openbmc_project/led/groups/enclosure_identify",
879c5b2abe0SLewanczyk, Dawid                     "org.freedesktop.DBus.Properties", "Set",
880c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.Led.Group", "Asserted",
881c5b2abe0SLewanczyk, Dawid                     sdbusplus::message::variant<bool>(
8826617338dSEd Tanous                         (dbusLedState ==
8836617338dSEd Tanous                                  "xyz.openbmc_project.Led.Physical.Action.Off"
8846617338dSEd Tanous                              ? false
8856617338dSEd Tanous                              : true)));
886c5b2abe0SLewanczyk, Dawid                 // Update identify led status
88755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
88855c7b7a2SEd Tanous                 crow::connections::systemBus->async_method_call(
8896617338dSEd Tanous                     [asyncResp{std::move(asyncResp)},
8906617338dSEd Tanous                      reqLedState{std::move(*reqLedState)}](
891c5b2abe0SLewanczyk, Dawid                         const boost::system::error_code ec) {
8921abe55efSEd Tanous                         if (ec)
8931abe55efSEd Tanous                         {
89455c7b7a2SEd Tanous                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
8956617338dSEd Tanous                             asyncResp->res.result(boost::beast::http::status::
8966617338dSEd Tanous                                                       internal_server_error);
897c5b2abe0SLewanczyk, Dawid                             return;
898c5b2abe0SLewanczyk, Dawid                         }
89955c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Led state update done.";
9006617338dSEd Tanous                         asyncResp->res.jsonValue["IndicatorLED"] =
9016617338dSEd Tanous                             std::move(reqLedState);
902c5b2abe0SLewanczyk, Dawid                     },
903c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.LED.Controller.identify",
904c5b2abe0SLewanczyk, Dawid                     "/xyz/openbmc_project/led/physical/identify",
905c5b2abe0SLewanczyk, Dawid                     "org.freedesktop.DBus.Properties", "Set",
906c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.Led.Physical", "State",
9076617338dSEd Tanous                     sdbusplus::message::variant<std::string>(dbusLedState));
9086617338dSEd Tanous             }
9096617338dSEd Tanous             else
9106617338dSEd Tanous             {
9116617338dSEd Tanous                 messages::addMessageToErrorJson(
9126617338dSEd Tanous                     asyncResp->res.jsonValue,
9136617338dSEd Tanous                     messages::propertyNotWritable(item.key()));
9146617338dSEd Tanous                 return;
9156617338dSEd Tanous             }
916c5b2abe0SLewanczyk, Dawid         }
917c5b2abe0SLewanczyk, Dawid     }
918c5b2abe0SLewanczyk, Dawid };
919c5b2abe0SLewanczyk, Dawid } // namespace redfish
920