xref: /openbmc/bmcweb/redfish-core/lib/systems.hpp (revision 9712f8ac42746e65f32c2bc3de0835846652568e)
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 
18*9712f8acSEd Tanous #include <boost/container/flat_map.hpp>
19*9712f8acSEd Tanous #include <node.hpp>
20c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
21c5b2abe0SLewanczyk, Dawid 
221abe55efSEd Tanous namespace redfish
231abe55efSEd Tanous {
24c5b2abe0SLewanczyk, Dawid 
25c5b2abe0SLewanczyk, Dawid /**
26c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
27c5b2abe0SLewanczyk, Dawid  *
28c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
29c5b2abe0SLewanczyk, Dawid  * @param[in] name  Computer system name from request
30c5b2abe0SLewanczyk, Dawid  *
31c5b2abe0SLewanczyk, Dawid  * @return None.
32c5b2abe0SLewanczyk, Dawid  */
33a0803efaSEd Tanous void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
341abe55efSEd Tanous                        const std::string &name)
351abe55efSEd Tanous {
3655c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
3755c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
38c5b2abe0SLewanczyk, Dawid         [name, aResp{std::move(aResp)}](
39c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
40c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
416c34de48SEd Tanous                 std::string,
426c34de48SEd Tanous                 std::vector<std::pair<std::string, std::vector<std::string>>>>>
43c5b2abe0SLewanczyk, Dawid                 &subtree) {
441abe55efSEd Tanous             if (ec)
451abe55efSEd Tanous             {
4655c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
47a0803efaSEd Tanous                 aResp->res.result(
48a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
49c5b2abe0SLewanczyk, Dawid                 return;
50c5b2abe0SLewanczyk, Dawid             }
51c5b2abe0SLewanczyk, Dawid             bool foundName = false;
52c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
536c34de48SEd Tanous             for (const std::pair<std::string,
546c34de48SEd Tanous                                  std::vector<std::pair<
556c34de48SEd Tanous                                      std::string, std::vector<std::string>>>>
561abe55efSEd Tanous                      &object : subtree)
571abe55efSEd Tanous             {
58c5b2abe0SLewanczyk, Dawid                 const std::string &path = object.first;
5955c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
601abe55efSEd Tanous                 const std::vector<
611abe55efSEd Tanous                     std::pair<std::string, std::vector<std::string>>>
62c5b2abe0SLewanczyk, Dawid                     &connectionNames = object.second;
631abe55efSEd Tanous                 if (connectionNames.size() < 1)
641abe55efSEd Tanous                 {
65c5b2abe0SLewanczyk, Dawid                     continue;
66c5b2abe0SLewanczyk, Dawid                 }
67c5b2abe0SLewanczyk, Dawid                 // Check if computer system exist
681abe55efSEd Tanous                 if (boost::ends_with(path, name))
691abe55efSEd Tanous                 {
70c5b2abe0SLewanczyk, Dawid                     foundName = true;
7155c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Found name: " << name;
726c34de48SEd Tanous                     const std::string connectionName = connectionNames[0].first;
7355c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
74c5b2abe0SLewanczyk, Dawid                         [aResp, name(std::string(name))](
75c5b2abe0SLewanczyk, Dawid                             const boost::system::error_code ec,
766c34de48SEd Tanous                             const std::vector<std::pair<
776c34de48SEd Tanous                                 std::string, VariantType>> &propertiesList) {
781abe55efSEd Tanous                             if (ec)
791abe55efSEd Tanous                             {
801abe55efSEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error: "
811abe55efSEd Tanous                                                  << ec;
826c34de48SEd Tanous                                 aResp->res.result(boost::beast::http::status::
83a0803efaSEd Tanous                                                       internal_server_error);
84c5b2abe0SLewanczyk, Dawid                                 return;
85c5b2abe0SLewanczyk, Dawid                             }
866c34de48SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
87c5b2abe0SLewanczyk, Dawid                                              << "properties for system";
881abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
891abe55efSEd Tanous                                      &property : propertiesList)
901abe55efSEd Tanous                             {
91c5b2abe0SLewanczyk, Dawid                                 const std::string *value =
921abe55efSEd Tanous                                     mapbox::getPtr<const std::string>(
931abe55efSEd Tanous                                         property.second);
941abe55efSEd Tanous                                 if (value != nullptr)
951abe55efSEd Tanous                                 {
961abe55efSEd Tanous                                     aResp->res.jsonValue[property.first] =
971abe55efSEd Tanous                                         *value;
98c5b2abe0SLewanczyk, Dawid                                 }
99c5b2abe0SLewanczyk, Dawid                             }
10055c7b7a2SEd Tanous                             aResp->res.jsonValue["Name"] = name;
10155c7b7a2SEd Tanous                             aResp->res.jsonValue["Id"] =
10255c7b7a2SEd Tanous                                 aResp->res.jsonValue["SerialNumber"];
103c5b2abe0SLewanczyk, Dawid                         },
1046c34de48SEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
1056c34de48SEd Tanous                         "GetAll",
1061abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
1071abe55efSEd Tanous                 }
1081abe55efSEd Tanous                 else
1091abe55efSEd Tanous                 {
1106c34de48SEd Tanous                     // This is not system, so check if it's cpu, dimm, UUID or
1116c34de48SEd Tanous                     // BiosVer
11204a258f4SEd Tanous                     for (const auto &connection : connectionNames)
1131abe55efSEd Tanous                     {
11404a258f4SEd Tanous                         for (const auto &interfaceName : connection.second)
1151abe55efSEd Tanous                         {
11604a258f4SEd Tanous                             if (interfaceName ==
11704a258f4SEd Tanous                                 "xyz.openbmc_project.Inventory.Item.Dimm")
1181abe55efSEd Tanous                             {
1191abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
12004a258f4SEd Tanous                                     << "Found Dimm, now get its properties.";
12155c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
1226617338dSEd Tanous                                     [aResp](
1231abe55efSEd Tanous                                         const boost::system::error_code ec,
1246c34de48SEd Tanous                                         const std::vector<
1256c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
1261abe55efSEd Tanous                                             &properties) {
1271abe55efSEd Tanous                                         if (ec)
1281abe55efSEd Tanous                                         {
1291abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
1306c34de48SEd Tanous                                                 << "DBUS response error " << ec;
131a0803efaSEd Tanous                                             aResp->res.result(
132a0803efaSEd Tanous                                                 boost::beast::http::status::
133a0803efaSEd Tanous                                                     internal_server_error);
134c5b2abe0SLewanczyk, Dawid                                             return;
135c5b2abe0SLewanczyk, Dawid                                         }
1366c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
1376c34de48SEd Tanous                                                          << properties.size()
138c5b2abe0SLewanczyk, Dawid                                                          << "Dimm properties.";
13904a258f4SEd Tanous                                         for (const std::pair<std::string,
14004a258f4SEd Tanous                                                              VariantType>
14104a258f4SEd Tanous                                                  &property : properties)
1421abe55efSEd Tanous                                         {
14304a258f4SEd Tanous                                             if (property.first ==
14404a258f4SEd Tanous                                                 "MemorySizeInKb")
1451abe55efSEd Tanous                                             {
14604a258f4SEd Tanous                                                 const uint64_t *value =
1471abe55efSEd Tanous                                                     mapbox::getPtr<
14804a258f4SEd Tanous                                                         const uint64_t>(
14904a258f4SEd Tanous                                                         property.second);
15004a258f4SEd Tanous                                                 if (value != nullptr)
1511abe55efSEd Tanous                                                 {
1521abe55efSEd Tanous                                                     aResp->res.jsonValue
1536c34de48SEd Tanous                                                         ["TotalSystemMemoryGi"
1546c34de48SEd Tanous                                                          "B"] +=
15504a258f4SEd Tanous                                                         *value / (1024 * 1024);
1561abe55efSEd Tanous                                                     aResp->res.jsonValue
1571abe55efSEd Tanous                                                         ["MemorySummary"]
1586c34de48SEd Tanous                                                         ["Status"]["State"] =
1591abe55efSEd Tanous                                                         "Enabled";
160c5b2abe0SLewanczyk, Dawid                                                 }
161c5b2abe0SLewanczyk, Dawid                                             }
162c5b2abe0SLewanczyk, Dawid                                         }
163c5b2abe0SLewanczyk, Dawid                                     },
16404a258f4SEd Tanous                                     connection.first, path,
1656c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
1666c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Dimm");
1671abe55efSEd Tanous                             }
16804a258f4SEd Tanous                             else if (interfaceName ==
16904a258f4SEd Tanous                                      "xyz.openbmc_project.Inventory.Item.Cpu")
1701abe55efSEd Tanous                             {
1711abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
17204a258f4SEd Tanous                                     << "Found Cpu, now get its properties.";
173a0803efaSEd Tanous                                 crow::connections::systemBus->async_method_call(
1746617338dSEd Tanous                                     [aResp](
175a0803efaSEd Tanous                                         const boost::system::error_code ec,
1766c34de48SEd Tanous                                         const std::vector<
1776c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
1781abe55efSEd Tanous                                             &properties) {
1791abe55efSEd Tanous                                         if (ec)
1801abe55efSEd Tanous                                         {
1811abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
1826c34de48SEd Tanous                                                 << "DBUS response error " << ec;
183a0803efaSEd Tanous                                             aResp->res.result(
184a0803efaSEd Tanous                                                 boost::beast::http::status::
185a0803efaSEd Tanous                                                     internal_server_error);
186c5b2abe0SLewanczyk, Dawid                                             return;
187c5b2abe0SLewanczyk, Dawid                                         }
1886c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
1896c34de48SEd Tanous                                                          << properties.size()
190c5b2abe0SLewanczyk, Dawid                                                          << "Cpu properties.";
19104a258f4SEd Tanous                                         for (const auto &property : properties)
1921abe55efSEd Tanous                                         {
19304a258f4SEd Tanous                                             if (property.first ==
19404a258f4SEd Tanous                                                 "ProcessorFamily")
1951abe55efSEd Tanous                                             {
196a0803efaSEd Tanous                                                 const std::string *value =
1971abe55efSEd Tanous                                                     mapbox::getPtr<
198a0803efaSEd Tanous                                                         const std::string>(
19904a258f4SEd Tanous                                                         property.second);
2001abe55efSEd Tanous                                                 if (value != nullptr)
2011abe55efSEd Tanous                                                 {
20204a258f4SEd Tanous                                                     nlohmann::json
20304a258f4SEd Tanous                                                         &procSummary =
2041abe55efSEd Tanous                                                             aResp->res.jsonValue
2056c34de48SEd Tanous                                                                 ["ProcessorSumm"
20604a258f4SEd Tanous                                                                  "ary"];
20704a258f4SEd Tanous                                                     nlohmann::json &procCount =
20804a258f4SEd Tanous                                                         procSummary["Count"];
20904a258f4SEd Tanous 
21004a258f4SEd Tanous                                                     procCount =
21104a258f4SEd Tanous                                                         procCount.get<int>() +
212c5b2abe0SLewanczyk, Dawid                                                         1;
21304a258f4SEd Tanous                                                     procSummary["Status"]
21404a258f4SEd Tanous                                                                ["State"] =
215c5b2abe0SLewanczyk, Dawid                                                                    "Enabled";
21604a258f4SEd Tanous                                                     procSummary["Model"] =
21704a258f4SEd Tanous                                                         *value;
218c5b2abe0SLewanczyk, Dawid                                                 }
219c5b2abe0SLewanczyk, Dawid                                             }
220c5b2abe0SLewanczyk, Dawid                                         }
221c5b2abe0SLewanczyk, Dawid                                     },
22204a258f4SEd Tanous                                     connection.first, path,
2236c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
2246c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Cpu");
2251abe55efSEd Tanous                             }
22604a258f4SEd Tanous                             else if (interfaceName ==
22704a258f4SEd Tanous                                      "xyz.openbmc_project.Common.UUID")
2281abe55efSEd Tanous                             {
2291abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
23004a258f4SEd Tanous                                     << "Found UUID, now get its properties.";
23155c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
2321abe55efSEd Tanous                                     [aResp](
2331abe55efSEd Tanous                                         const boost::system::error_code ec,
2346c34de48SEd Tanous                                         const std::vector<
2356c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
2361abe55efSEd Tanous                                             &properties) {
2371abe55efSEd Tanous                                         if (ec)
2381abe55efSEd Tanous                                         {
2391abe55efSEd Tanous                                             BMCWEB_LOG_DEBUG
2406c34de48SEd Tanous                                                 << "DBUS response error " << ec;
241a0803efaSEd Tanous                                             aResp->res.result(
242a0803efaSEd Tanous                                                 boost::beast::http::status::
243a0803efaSEd Tanous                                                     internal_server_error);
244c5b2abe0SLewanczyk, Dawid                                             return;
245c5b2abe0SLewanczyk, Dawid                                         }
2466c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
2476c34de48SEd Tanous                                                          << properties.size()
248c5b2abe0SLewanczyk, Dawid                                                          << "UUID properties.";
2491abe55efSEd Tanous                                         for (const std::pair<std::string,
25004a258f4SEd Tanous                                                              VariantType>
25104a258f4SEd Tanous                                                  &property : properties)
2521abe55efSEd Tanous                                         {
25304a258f4SEd Tanous                                             if (property.first == "BIOSVer")
2541abe55efSEd Tanous                                             {
255c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
2561abe55efSEd Tanous                                                     mapbox::getPtr<
2571abe55efSEd Tanous                                                         const std::string>(
25804a258f4SEd Tanous                                                         property.second);
2591abe55efSEd Tanous                                                 if (value != nullptr)
2601abe55efSEd Tanous                                                 {
2611abe55efSEd Tanous                                                     aResp->res.jsonValue
2621abe55efSEd Tanous                                                         ["BiosVersion"] =
2631abe55efSEd Tanous                                                         *value;
264c5b2abe0SLewanczyk, Dawid                                                 }
265c5b2abe0SLewanczyk, Dawid                                             }
26604a258f4SEd Tanous                                             if (property.first == "UUID")
2671abe55efSEd Tanous                                             {
268c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
2691abe55efSEd Tanous                                                     mapbox::getPtr<
2701abe55efSEd Tanous                                                         const std::string>(
27104a258f4SEd Tanous                                                         property.second);
27204a258f4SEd Tanous 
2731abe55efSEd Tanous                                                 if (value != nullptr)
2741abe55efSEd Tanous                                                 {
27504a258f4SEd Tanous                                                     std::string valueStr =
2761abe55efSEd Tanous                                                         *value;
27704a258f4SEd Tanous                                                     if (valueStr.size() == 32)
2781abe55efSEd Tanous                                                     {
27904a258f4SEd Tanous                                                         valueStr.insert(8, 1,
28004a258f4SEd Tanous                                                                         '-');
28104a258f4SEd Tanous                                                         valueStr.insert(13, 1,
28204a258f4SEd Tanous                                                                         '-');
28304a258f4SEd Tanous                                                         valueStr.insert(18, 1,
28404a258f4SEd Tanous                                                                         '-');
28504a258f4SEd Tanous                                                         valueStr.insert(23, 1,
28604a258f4SEd Tanous                                                                         '-');
28704a258f4SEd Tanous                                                     }
28804a258f4SEd Tanous                                                     BMCWEB_LOG_DEBUG
28904a258f4SEd Tanous                                                         << "UUID = "
29004a258f4SEd Tanous                                                         << valueStr;
2916c34de48SEd Tanous                                                     aResp->res
2926c34de48SEd Tanous                                                         .jsonValue["UUID"] =
29304a258f4SEd Tanous                                                         valueStr;
294c5b2abe0SLewanczyk, Dawid                                                 }
295c5b2abe0SLewanczyk, Dawid                                             }
296c5b2abe0SLewanczyk, Dawid                                         }
297c5b2abe0SLewanczyk, Dawid                                     },
29804a258f4SEd Tanous                                     connection.first, path,
2996c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
3001abe55efSEd Tanous                                     "xyz.openbmc_project.Common.UUID");
301c5b2abe0SLewanczyk, Dawid                             }
302c5b2abe0SLewanczyk, Dawid                         }
303c5b2abe0SLewanczyk, Dawid                     }
304c5b2abe0SLewanczyk, Dawid                 }
305c5b2abe0SLewanczyk, Dawid             }
3061abe55efSEd Tanous             if (foundName == false)
3071abe55efSEd Tanous             {
308a0803efaSEd Tanous                 aResp->res.result(
309a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
310c5b2abe0SLewanczyk, Dawid             }
311c5b2abe0SLewanczyk, Dawid         },
312c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
313c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
314c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
3156617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
3166617338dSEd Tanous         std::array<const char *, 5>{
3176617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
3186617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
3196617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
3206617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
3216617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
3226617338dSEd Tanous         });
323c5b2abe0SLewanczyk, Dawid }
324c5b2abe0SLewanczyk, Dawid 
325c5b2abe0SLewanczyk, Dawid /**
326c5b2abe0SLewanczyk, Dawid  * @brief Retrieves identify led group properties over dbus
327c5b2abe0SLewanczyk, Dawid  *
328c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
329c5b2abe0SLewanczyk, Dawid  * @param[in] callback  Callback for process retrieved data.
330c5b2abe0SLewanczyk, Dawid  *
331c5b2abe0SLewanczyk, Dawid  * @return None.
332c5b2abe0SLewanczyk, Dawid  */
333c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
334a0803efaSEd Tanous void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
3351abe55efSEd Tanous                          CallbackFunc &&callback)
3361abe55efSEd Tanous {
33755c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get led groups";
33855c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
3391abe55efSEd Tanous         [aResp{std::move(aResp)},
3406617338dSEd Tanous          callback{std::move(callback)}](const boost::system::error_code &ec,
3411abe55efSEd Tanous                                         const ManagedObjectsType &resp) {
3421abe55efSEd Tanous             if (ec)
3431abe55efSEd Tanous             {
34455c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
345a0803efaSEd Tanous                 aResp->res.result(
346a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
347c5b2abe0SLewanczyk, Dawid                 return;
348c5b2abe0SLewanczyk, Dawid             }
3496c34de48SEd Tanous             BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
3501abe55efSEd Tanous             for (const auto &objPath : resp)
3511abe55efSEd Tanous             {
352c5b2abe0SLewanczyk, Dawid                 const std::string &path = objPath.first;
3531abe55efSEd Tanous                 if (path.rfind("enclosure_identify") != std::string::npos)
3541abe55efSEd Tanous                 {
3551abe55efSEd Tanous                     for (const auto &interface : objPath.second)
3561abe55efSEd Tanous                     {
3576c34de48SEd Tanous                         if (interface.first == "xyz.openbmc_project.Led.Group")
3581abe55efSEd Tanous                         {
3591abe55efSEd Tanous                             for (const auto &property : interface.second)
3601abe55efSEd Tanous                             {
3611abe55efSEd Tanous                                 if (property.first == "Asserted")
3621abe55efSEd Tanous                                 {
363c5b2abe0SLewanczyk, Dawid                                     const bool *asserted =
3641abe55efSEd Tanous                                         mapbox::getPtr<const bool>(
3651abe55efSEd Tanous                                             property.second);
3661abe55efSEd Tanous                                     if (nullptr != asserted)
3671abe55efSEd Tanous                                     {
368c5b2abe0SLewanczyk, Dawid                                         callback(*asserted, aResp);
3691abe55efSEd Tanous                                     }
3701abe55efSEd Tanous                                     else
3711abe55efSEd Tanous                                     {
372c5b2abe0SLewanczyk, Dawid                                         callback(false, aResp);
373c5b2abe0SLewanczyk, Dawid                                     }
374c5b2abe0SLewanczyk, Dawid                                 }
375c5b2abe0SLewanczyk, Dawid                             }
376c5b2abe0SLewanczyk, Dawid                         }
377c5b2abe0SLewanczyk, Dawid                     }
378c5b2abe0SLewanczyk, Dawid                 }
379c5b2abe0SLewanczyk, Dawid             }
380c5b2abe0SLewanczyk, Dawid         },
381c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.GroupManager",
3826c34de48SEd Tanous         "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
3836c34de48SEd Tanous         "GetManagedObjects");
384c5b2abe0SLewanczyk, Dawid }
385c5b2abe0SLewanczyk, Dawid 
386c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
3876c34de48SEd Tanous void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
3881abe55efSEd Tanous {
38955c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get identify led properties";
39055c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
3916617338dSEd Tanous         [aResp,
3926617338dSEd Tanous          callback{std::move(callback)}](const boost::system::error_code ec,
393c5b2abe0SLewanczyk, Dawid                                         const PropertiesType &properties) {
3941abe55efSEd Tanous             if (ec)
3951abe55efSEd Tanous             {
39655c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
397a0803efaSEd Tanous                 aResp->res.result(
398a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
399c5b2abe0SLewanczyk, Dawid                 return;
400c5b2abe0SLewanczyk, Dawid             }
4011abe55efSEd Tanous             BMCWEB_LOG_DEBUG << "Got " << properties.size()
4021abe55efSEd Tanous                              << "led properties.";
403c5b2abe0SLewanczyk, Dawid             std::string output;
4041abe55efSEd Tanous             for (const auto &property : properties)
4051abe55efSEd Tanous             {
4061abe55efSEd Tanous                 if (property.first == "State")
4071abe55efSEd Tanous                 {
408c5b2abe0SLewanczyk, Dawid                     const std::string *s =
40955c7b7a2SEd Tanous                         mapbox::getPtr<std::string>(property.second);
4101abe55efSEd Tanous                     if (nullptr != s)
4111abe55efSEd Tanous                     {
41255c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
413c5b2abe0SLewanczyk, Dawid                         const auto pos = s->rfind('.');
4141abe55efSEd Tanous                         if (pos != std::string::npos)
4151abe55efSEd Tanous                         {
416c5b2abe0SLewanczyk, Dawid                             auto led = s->substr(pos + 1);
4171abe55efSEd Tanous                             for (const std::pair<const char *, const char *>
4181abe55efSEd Tanous                                      &p :
4191abe55efSEd Tanous                                  std::array<
4206c34de48SEd Tanous                                      std::pair<const char *, const char *>, 3>{
4216c34de48SEd Tanous                                      {{"On", "Lit"},
422c5b2abe0SLewanczyk, Dawid                                       {"Blink", "Blinking"},
4231abe55efSEd Tanous                                       {"Off", "Off"}}})
4241abe55efSEd Tanous                             {
4251abe55efSEd Tanous                                 if (led == p.first)
4261abe55efSEd Tanous                                 {
427c5b2abe0SLewanczyk, Dawid                                     output = p.second;
428c5b2abe0SLewanczyk, Dawid                                 }
429c5b2abe0SLewanczyk, Dawid                             }
430c5b2abe0SLewanczyk, Dawid                         }
431c5b2abe0SLewanczyk, Dawid                     }
432c5b2abe0SLewanczyk, Dawid                 }
433c5b2abe0SLewanczyk, Dawid             }
434c5b2abe0SLewanczyk, Dawid             callback(output, aResp);
435c5b2abe0SLewanczyk, Dawid         },
436c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.Controller.identify",
437c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/led/physical/identify",
438c5b2abe0SLewanczyk, Dawid         "org.freedesktop.DBus.Properties", "GetAll",
439c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Led.Physical");
440c5b2abe0SLewanczyk, Dawid }
441c5b2abe0SLewanczyk, Dawid 
442c5b2abe0SLewanczyk, Dawid /**
443c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
444c5b2abe0SLewanczyk, Dawid  *
445c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
446c5b2abe0SLewanczyk, Dawid  *
447c5b2abe0SLewanczyk, Dawid  * @return None.
448c5b2abe0SLewanczyk, Dawid  */
449a0803efaSEd Tanous void getHostState(std::shared_ptr<AsyncResp> aResp)
4501abe55efSEd Tanous {
45155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
45255c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
4536617338dSEd Tanous         [aResp{std::move(aResp)}](
4546617338dSEd Tanous             const boost::system::error_code ec,
4556617338dSEd Tanous             const sdbusplus::message::variant<std::string> &hostState) {
4561abe55efSEd Tanous             if (ec)
4571abe55efSEd Tanous             {
45855c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
459a0803efaSEd Tanous                 aResp->res.result(
460a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
461c5b2abe0SLewanczyk, Dawid                 return;
462c5b2abe0SLewanczyk, Dawid             }
4636617338dSEd Tanous 
4646617338dSEd Tanous             const std::string *s = mapbox::getPtr<const std::string>(hostState);
46555c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
4666617338dSEd Tanous             if (s != nullptr)
4671abe55efSEd Tanous             {
468c5b2abe0SLewanczyk, Dawid                 // Verify Host State
4696617338dSEd Tanous                 if (*s == "xyz.openbmc_project.State.Host.Running")
4701abe55efSEd Tanous                 {
47155c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
4726617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
4731abe55efSEd Tanous                 }
4741abe55efSEd Tanous                 else
4751abe55efSEd Tanous                 {
47655c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
4776617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
478c5b2abe0SLewanczyk, Dawid                 }
479c5b2abe0SLewanczyk, Dawid             }
480c5b2abe0SLewanczyk, Dawid         },
4816c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
4826617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
4836617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
484c5b2abe0SLewanczyk, Dawid }
485c5b2abe0SLewanczyk, Dawid 
486c5b2abe0SLewanczyk, Dawid /**
487c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
488c5b2abe0SLewanczyk, Dawid  * Schema
489c5b2abe0SLewanczyk, Dawid  */
4901abe55efSEd Tanous class SystemsCollection : public Node
4911abe55efSEd Tanous {
492c5b2abe0SLewanczyk, Dawid   public:
4931abe55efSEd Tanous     SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
4941abe55efSEd Tanous     {
495c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] =
496c5b2abe0SLewanczyk, Dawid             "#ComputerSystemCollection.ComputerSystemCollection";
497c5b2abe0SLewanczyk, Dawid         Node::json["@odata.id"] = "/redfish/v1/Systems";
498c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
499c5b2abe0SLewanczyk, Dawid             "/redfish/v1/"
500c5b2abe0SLewanczyk, Dawid             "$metadata#ComputerSystemCollection.ComputerSystemCollection";
501c5b2abe0SLewanczyk, Dawid         Node::json["Name"] = "Computer System Collection";
502c5b2abe0SLewanczyk, Dawid 
503c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
504c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
505c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
506c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
507c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
508c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
509c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
510c5b2abe0SLewanczyk, Dawid     }
511c5b2abe0SLewanczyk, Dawid 
512c5b2abe0SLewanczyk, Dawid   private:
51355c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
5141abe55efSEd Tanous                const std::vector<std::string> &params) override
5151abe55efSEd Tanous     {
5166617338dSEd Tanous         BMCWEB_LOG_DEBUG << "Get list of available boards.";
5176617338dSEd Tanous         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
5186617338dSEd Tanous         res.jsonValue = Node::json;
5196617338dSEd Tanous         crow::connections::systemBus->async_method_call(
5206617338dSEd Tanous             [asyncResp](const boost::system::error_code ec,
5216617338dSEd Tanous                         const std::vector<std::string> &resp) {
5226617338dSEd Tanous                 if (ec)
5231abe55efSEd Tanous                 {
5246617338dSEd Tanous                     asyncResp->res.result(
5256617338dSEd Tanous                         boost::beast::http::status::internal_server_error);
5266617338dSEd Tanous                     return;
5276617338dSEd Tanous                 }
5286617338dSEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
5296617338dSEd Tanous 
530c5b2abe0SLewanczyk, Dawid                 // ... prepare json array with appropriate @odata.id links
5316617338dSEd Tanous                 nlohmann::json &boardArray =
5326617338dSEd Tanous                     asyncResp->res.jsonValue["Members"];
5336617338dSEd Tanous                 boardArray = nlohmann::json::array();
5346617338dSEd Tanous 
5356617338dSEd Tanous                 // Iterate over all retrieved ObjectPaths.
5366617338dSEd Tanous                 for (const std::string &objpath : resp)
5376617338dSEd Tanous                 {
5386617338dSEd Tanous                     std::size_t lastPos = objpath.rfind("/");
5396617338dSEd Tanous                     if (lastPos != std::string::npos)
5401abe55efSEd Tanous                     {
541c5b2abe0SLewanczyk, Dawid                         boardArray.push_back(
5426617338dSEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/" +
5436617338dSEd Tanous                                                objpath.substr(lastPos + 1)}});
544c5b2abe0SLewanczyk, Dawid                     }
5451abe55efSEd Tanous                 }
5466617338dSEd Tanous 
5476617338dSEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] =
5486617338dSEd Tanous                     boardArray.size();
5496617338dSEd Tanous             },
5506617338dSEd Tanous             "xyz.openbmc_project.ObjectMapper",
5516617338dSEd Tanous             "/xyz/openbmc_project/object_mapper",
5526617338dSEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
5536617338dSEd Tanous             "/xyz/openbmc_project/inventory", int32_t(0),
5546617338dSEd Tanous             std::array<const char *, 1>{
5556617338dSEd Tanous                 "xyz.openbmc_project.Inventory.Item.Board"});
556c5b2abe0SLewanczyk, Dawid     }
557c5b2abe0SLewanczyk, Dawid };
558c5b2abe0SLewanczyk, Dawid 
559c5b2abe0SLewanczyk, Dawid /**
560cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
561cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
562cc340dd9SEd Tanous  */
563cc340dd9SEd Tanous class SystemActionsReset : public Node
564cc340dd9SEd Tanous {
565cc340dd9SEd Tanous   public:
566cc340dd9SEd Tanous     SystemActionsReset(CrowApp &app) :
567cc340dd9SEd Tanous         Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
568cc340dd9SEd Tanous              std::string())
569cc340dd9SEd Tanous     {
570cc340dd9SEd Tanous         entityPrivileges = {
571cc340dd9SEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
572cc340dd9SEd Tanous     }
573cc340dd9SEd Tanous 
574cc340dd9SEd Tanous   private:
575cc340dd9SEd Tanous     /**
576cc340dd9SEd Tanous      * Function handles POST method request.
577cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
578cc340dd9SEd Tanous      */
579cc340dd9SEd Tanous     void doPost(crow::Response &res, const crow::Request &req,
580cc340dd9SEd Tanous                 const std::vector<std::string> &params) override
581cc340dd9SEd Tanous     {
582cc340dd9SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
583cc340dd9SEd Tanous 
584*9712f8acSEd Tanous         std::string resetType;
585*9712f8acSEd Tanous         if (!json_util::readJson(req, res, "ResetType", resetType))
586cc340dd9SEd Tanous         {
587cc340dd9SEd Tanous             return;
588cc340dd9SEd Tanous         }
589cc340dd9SEd Tanous 
590*9712f8acSEd Tanous         if (resetType == "ForceOff")
591cc340dd9SEd Tanous         {
592cc340dd9SEd Tanous             // Force off acts on the chassis
593cc340dd9SEd Tanous             crow::connections::systemBus->async_method_call(
594cc340dd9SEd Tanous                 [asyncResp](const boost::system::error_code ec) {
595cc340dd9SEd Tanous                     if (ec)
596cc340dd9SEd Tanous                     {
597*9712f8acSEd Tanous                         BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
598cc340dd9SEd Tanous                         asyncResp->res.result(
599*9712f8acSEd Tanous                             boost::beast::http::status::internal_server_error);
600cc340dd9SEd Tanous                         return;
601cc340dd9SEd Tanous                     }
602cc340dd9SEd Tanous                     // TODO Consider support polling mechanism to verify
603cc340dd9SEd Tanous                     // status of host and chassis after execute the
604cc340dd9SEd Tanous                     // requested action.
605cc340dd9SEd Tanous                     BMCWEB_LOG_DEBUG << "Response with no content";
606cc340dd9SEd Tanous                     asyncResp->res.result(
607cc340dd9SEd Tanous                         boost::beast::http::status::no_content);
608cc340dd9SEd Tanous                 },
609cc340dd9SEd Tanous                 "xyz.openbmc_project.State.Chassis",
610cc340dd9SEd Tanous                 "/xyz/openbmc_project/state/chassis0",
611cc340dd9SEd Tanous                 "org.freedesktop.DBus.Properties", "Set",
612*9712f8acSEd Tanous                 "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
613cc340dd9SEd Tanous                 sdbusplus::message::variant<std::string>{
614*9712f8acSEd Tanous                     "xyz.openbmc_project.State.Chassis.Transition.Off"});
615cc340dd9SEd Tanous             return;
616cc340dd9SEd Tanous         }
617cc340dd9SEd Tanous         // all other actions operate on the host
618cc340dd9SEd Tanous         std::string command;
619cc340dd9SEd Tanous         // Execute Reset Action regarding to each reset type.
620*9712f8acSEd Tanous         if (resetType == "On")
621cc340dd9SEd Tanous         {
622cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.On";
623cc340dd9SEd Tanous         }
624*9712f8acSEd Tanous         else if (resetType == "GracefulShutdown")
625cc340dd9SEd Tanous         {
626cc340dd9SEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Off";
627cc340dd9SEd Tanous         }
628*9712f8acSEd Tanous         else if (resetType == "GracefulRestart")
629cc340dd9SEd Tanous         {
630*9712f8acSEd Tanous             command = "xyz.openbmc_project.State.Host.Transition.Reboot";
631cc340dd9SEd Tanous         }
632cc340dd9SEd Tanous         else
633cc340dd9SEd Tanous         {
634cc340dd9SEd Tanous             res.result(boost::beast::http::status::bad_request);
635cc340dd9SEd Tanous             messages::addMessageToErrorJson(
636cc340dd9SEd Tanous                 asyncResp->res.jsonValue,
637*9712f8acSEd Tanous                 messages::actionParameterUnknown("Reset", resetType));
638cc340dd9SEd Tanous             return;
639cc340dd9SEd Tanous         }
640cc340dd9SEd Tanous 
641cc340dd9SEd Tanous         crow::connections::systemBus->async_method_call(
642cc340dd9SEd Tanous             [asyncResp](const boost::system::error_code ec) {
643cc340dd9SEd Tanous                 if (ec)
644cc340dd9SEd Tanous                 {
645cc340dd9SEd Tanous                     BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
646*9712f8acSEd Tanous                     asyncResp->res.result(
647*9712f8acSEd Tanous                         boost::beast::http::status::internal_server_error);
648cc340dd9SEd Tanous                     return;
649cc340dd9SEd Tanous                 }
650cc340dd9SEd Tanous                 // TODO Consider support polling mechanism to verify
651cc340dd9SEd Tanous                 // status of host and chassis after execute the
652cc340dd9SEd Tanous                 // requested action.
653cc340dd9SEd Tanous                 BMCWEB_LOG_DEBUG << "Response with no content";
654*9712f8acSEd Tanous                 asyncResp->res.result(boost::beast::http::status::no_content);
655cc340dd9SEd Tanous             },
656cc340dd9SEd Tanous             "xyz.openbmc_project.State.Host",
657cc340dd9SEd Tanous             "/xyz/openbmc_project/state/host0",
658cc340dd9SEd Tanous             "org.freedesktop.DBus.Properties", "Set",
659*9712f8acSEd Tanous             "xyz.openbmc_project.State.Host", "RequestedHostTransition",
660cc340dd9SEd Tanous             sdbusplus::message::variant<std::string>{command});
661cc340dd9SEd Tanous     }
662cc340dd9SEd Tanous };
663cc340dd9SEd Tanous 
664cc340dd9SEd Tanous /**
6656617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
666c5b2abe0SLewanczyk, Dawid  */
6671abe55efSEd Tanous class Systems : public Node
6681abe55efSEd Tanous {
669c5b2abe0SLewanczyk, Dawid   public:
670c5b2abe0SLewanczyk, Dawid     /*
671c5b2abe0SLewanczyk, Dawid      * Default Constructor
672c5b2abe0SLewanczyk, Dawid      */
6731abe55efSEd Tanous     Systems(CrowApp &app) :
6741abe55efSEd Tanous         Node(app, "/redfish/v1/Systems/<str>/", std::string())
6751abe55efSEd Tanous     {
676c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
677c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
678c5b2abe0SLewanczyk, Dawid             "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
679c5b2abe0SLewanczyk, Dawid         Node::json["SystemType"] = "Physical";
680c5b2abe0SLewanczyk, Dawid         Node::json["Description"] = "Computer System";
681c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideEnabled"] =
682c5b2abe0SLewanczyk, Dawid             "Disabled"; // TODO(Dawid), get real boot data
683c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideTarget"] =
684c5b2abe0SLewanczyk, Dawid             "None"; // TODO(Dawid), get real boot data
685c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideMode"] =
686c5b2abe0SLewanczyk, Dawid             "Legacy"; // TODO(Dawid), get real boot data
6871abe55efSEd Tanous         Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
6881abe55efSEd Tanous             {"None",      "Pxe",       "Hdd", "Cd",
6891abe55efSEd Tanous              "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
6901abe55efSEd Tanous                                                // data
69104a258f4SEd Tanous         Node::json["ProcessorSummary"]["Count"] = 0;
692c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
693c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
694c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
695c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
696c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
697c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
698c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
699c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
700c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
701c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
702c5b2abe0SLewanczyk, Dawid     }
703c5b2abe0SLewanczyk, Dawid 
704c5b2abe0SLewanczyk, Dawid   private:
705c5b2abe0SLewanczyk, Dawid     /**
706c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
707c5b2abe0SLewanczyk, Dawid      */
70855c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
7091abe55efSEd Tanous                const std::vector<std::string> &params) override
7101abe55efSEd Tanous     {
711c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
712c5b2abe0SLewanczyk, Dawid         // impossible
7131abe55efSEd Tanous         if (params.size() != 1)
7141abe55efSEd Tanous         {
715c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
716c5b2abe0SLewanczyk, Dawid             res.end();
717c5b2abe0SLewanczyk, Dawid             return;
718c5b2abe0SLewanczyk, Dawid         }
719c5b2abe0SLewanczyk, Dawid 
720c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
721c5b2abe0SLewanczyk, Dawid 
72204a258f4SEd Tanous         res.jsonValue = Node::json;
72304a258f4SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
72404a258f4SEd Tanous 
725cc340dd9SEd Tanous         // TODO Need to support ForceRestart.
726cc340dd9SEd Tanous         res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
727cc340dd9SEd Tanous             {"target",
728cc340dd9SEd Tanous              "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
729cc340dd9SEd Tanous             {"ResetType@Redfish.AllowableValues",
730cc340dd9SEd Tanous              {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
731c5b2abe0SLewanczyk, Dawid 
732a0803efaSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
733c5b2abe0SLewanczyk, Dawid 
7346c34de48SEd Tanous         getLedGroupIdentify(
735a0803efaSEd Tanous             asyncResp,
736a0803efaSEd Tanous             [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
7371abe55efSEd Tanous                 if (asserted)
7381abe55efSEd Tanous                 {
739c5b2abe0SLewanczyk, Dawid                     // If led group is asserted, then another call is needed to
740c5b2abe0SLewanczyk, Dawid                     // get led status
7416c34de48SEd Tanous                     getLedIdentify(
742a0803efaSEd Tanous                         aResp, [](const std::string &ledStatus,
743a0803efaSEd Tanous                                   const std::shared_ptr<AsyncResp> &aResp) {
7441abe55efSEd Tanous                             if (!ledStatus.empty())
7451abe55efSEd Tanous                             {
7461abe55efSEd Tanous                                 aResp->res.jsonValue["IndicatorLED"] =
7471abe55efSEd Tanous                                     ledStatus;
748c5b2abe0SLewanczyk, Dawid                             }
749c5b2abe0SLewanczyk, Dawid                         });
7501abe55efSEd Tanous                 }
7511abe55efSEd Tanous                 else
7521abe55efSEd Tanous                 {
75355c7b7a2SEd Tanous                     aResp->res.jsonValue["IndicatorLED"] = "Off";
754c5b2abe0SLewanczyk, Dawid                 }
755c5b2abe0SLewanczyk, Dawid             });
7566c34de48SEd Tanous         getComputerSystem(asyncResp, name);
7576c34de48SEd Tanous         getHostState(asyncResp);
758c5b2abe0SLewanczyk, Dawid     }
759c5b2abe0SLewanczyk, Dawid 
76055c7b7a2SEd Tanous     void doPatch(crow::Response &res, const crow::Request &req,
7611abe55efSEd Tanous                  const std::vector<std::string> &params) override
7621abe55efSEd Tanous     {
763c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
764c5b2abe0SLewanczyk, Dawid         // impossible
7656617338dSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
7661abe55efSEd Tanous         if (params.size() != 1)
7671abe55efSEd Tanous         {
768c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
769c5b2abe0SLewanczyk, Dawid             return;
770c5b2abe0SLewanczyk, Dawid         }
771c5b2abe0SLewanczyk, Dawid 
7726617338dSEd Tanous         const std::string &name = params[0];
7736617338dSEd Tanous 
77455c7b7a2SEd Tanous         res.jsonValue = Node::json;
77555c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
776c5b2abe0SLewanczyk, Dawid 
777*9712f8acSEd Tanous         std::string indicatorLedTemp;
778*9712f8acSEd Tanous         boost::optional<std::string> indicatorLed = indicatorLedTemp;
779*9712f8acSEd Tanous         if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
7806617338dSEd Tanous         {
7816617338dSEd Tanous             return;
7826617338dSEd Tanous         }
7836617338dSEd Tanous 
784*9712f8acSEd Tanous         if (indicatorLed)
7856617338dSEd Tanous         {
786*9712f8acSEd Tanous             std::string dbusLedState;
787*9712f8acSEd Tanous             if (*indicatorLed == "On")
788*9712f8acSEd Tanous             {
789*9712f8acSEd Tanous                 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
7906617338dSEd Tanous             }
791*9712f8acSEd Tanous             else if (*indicatorLed == "Blink")
7926617338dSEd Tanous             {
7936617338dSEd Tanous                 dbusLedState =
7946617338dSEd Tanous                     "xyz.openbmc_project.Led.Physical.Action.Blinking";
7956617338dSEd Tanous             }
796*9712f8acSEd Tanous             else if (*indicatorLed == "Off")
7976617338dSEd Tanous             {
798*9712f8acSEd Tanous                 dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
7996617338dSEd Tanous             }
8006617338dSEd Tanous             else
8016617338dSEd Tanous             {
8026617338dSEd Tanous                 messages::addMessageToJsonRoot(
8036617338dSEd Tanous                     res.jsonValue, messages::propertyValueNotInList(
804*9712f8acSEd Tanous                                        *indicatorLed, "IndicatorLED"));
8056617338dSEd Tanous                 return;
8066617338dSEd Tanous             }
8076617338dSEd Tanous 
8086c34de48SEd Tanous             getHostState(asyncResp);
8096c34de48SEd Tanous             getComputerSystem(asyncResp, name);
810c5b2abe0SLewanczyk, Dawid 
811c5b2abe0SLewanczyk, Dawid             // Update led group
81255c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Update led group.";
81355c7b7a2SEd Tanous             crow::connections::systemBus->async_method_call(
8146617338dSEd Tanous                 [asyncResp{std::move(asyncResp)}](
815c5b2abe0SLewanczyk, Dawid                     const boost::system::error_code ec) {
8161abe55efSEd Tanous                     if (ec)
8171abe55efSEd Tanous                     {
81855c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
819*9712f8acSEd Tanous                         asyncResp->res.result(
820*9712f8acSEd Tanous                             boost::beast::http::status::internal_server_error);
821c5b2abe0SLewanczyk, Dawid                         return;
822c5b2abe0SLewanczyk, Dawid                     }
82355c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Led group update done.";
824c5b2abe0SLewanczyk, Dawid                 },
825c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.LED.GroupManager",
826c5b2abe0SLewanczyk, Dawid                 "/xyz/openbmc_project/led/groups/enclosure_identify",
827c5b2abe0SLewanczyk, Dawid                 "org.freedesktop.DBus.Properties", "Set",
828c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Led.Group", "Asserted",
829c5b2abe0SLewanczyk, Dawid                 sdbusplus::message::variant<bool>(
8306617338dSEd Tanous                     (dbusLedState ==
8316617338dSEd Tanous                              "xyz.openbmc_project.Led.Physical.Action.Off"
8326617338dSEd Tanous                          ? false
8336617338dSEd Tanous                          : true)));
834c5b2abe0SLewanczyk, Dawid             // Update identify led status
83555c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
83655c7b7a2SEd Tanous             crow::connections::systemBus->async_method_call(
8376617338dSEd Tanous                 [asyncResp{std::move(asyncResp)},
838*9712f8acSEd Tanous                  indicatorLed{std::move(*indicatorLed)}](
839c5b2abe0SLewanczyk, Dawid                     const boost::system::error_code ec) {
8401abe55efSEd Tanous                     if (ec)
8411abe55efSEd Tanous                     {
84255c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
843*9712f8acSEd Tanous                         asyncResp->res.result(
844*9712f8acSEd Tanous                             boost::beast::http::status::internal_server_error);
845c5b2abe0SLewanczyk, Dawid                         return;
846c5b2abe0SLewanczyk, Dawid                     }
84755c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Led state update done.";
8486617338dSEd Tanous                     asyncResp->res.jsonValue["IndicatorLED"] =
849*9712f8acSEd Tanous                         std::move(indicatorLed);
850c5b2abe0SLewanczyk, Dawid                 },
851c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.LED.Controller.identify",
852c5b2abe0SLewanczyk, Dawid                 "/xyz/openbmc_project/led/physical/identify",
853c5b2abe0SLewanczyk, Dawid                 "org.freedesktop.DBus.Properties", "Set",
854c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Led.Physical", "State",
8556617338dSEd Tanous                 sdbusplus::message::variant<std::string>(dbusLedState));
8566617338dSEd Tanous         }
857c5b2abe0SLewanczyk, Dawid     }
858c5b2abe0SLewanczyk, Dawid };
859c5b2abe0SLewanczyk, Dawid } // namespace redfish
860