xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 6c34de481a1efde57a17456a03948de6bf27aa10)
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 <error_messages.hpp>
22c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
23c5b2abe0SLewanczyk, Dawid 
241abe55efSEd Tanous namespace redfish
251abe55efSEd Tanous {
26c5b2abe0SLewanczyk, Dawid 
27*6c34de48SEd Tanous template <typename CallbackFunc> void getBaseboardList(CallbackFunc &&callback)
281abe55efSEd Tanous {
2955c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get list of available boards.";
3055c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
31*6c34de48SEd Tanous         [callback{std::move(callback)}](const boost::system::error_code ec,
32c5b2abe0SLewanczyk, Dawid                                         const std::vector<std::string> &resp) {
33*6c34de48SEd Tanous             // Callback requires vector<string> to retrieve all available board
34*6c34de48SEd Tanous             // list.
35d76323e5SEd Tanous             std::vector<std::string> boardList;
361abe55efSEd Tanous             if (ec)
371abe55efSEd Tanous             {
38*6c34de48SEd Tanous                 // Something wrong on DBus, the error_code is not important at
39*6c34de48SEd Tanous                 // this moment, just return success=false, and empty output.
40*6c34de48SEd Tanous                 // Since size of vector may vary depending on information from
41*6c34de48SEd Tanous                 // Entity Manager, and empty output could not be treated same
42*6c34de48SEd Tanous                 // way as error.
43d76323e5SEd Tanous                 callback(false, boardList);
44c5b2abe0SLewanczyk, Dawid                 return;
45c5b2abe0SLewanczyk, Dawid             }
4655c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
47c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
481abe55efSEd Tanous             for (const std::string &objpath : resp)
491abe55efSEd Tanous             {
50d76323e5SEd Tanous                 std::size_t lastPos = objpath.rfind("/");
511abe55efSEd Tanous                 if (lastPos != std::string::npos)
521abe55efSEd Tanous                 {
53d76323e5SEd Tanous                     boardList.emplace_back(objpath.substr(lastPos + 1));
54c5b2abe0SLewanczyk, Dawid                 }
55c5b2abe0SLewanczyk, Dawid             }
56c5b2abe0SLewanczyk, Dawid             // Finally make a callback with useful data
57d76323e5SEd Tanous             callback(true, boardList);
58c5b2abe0SLewanczyk, Dawid         },
59c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
60c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
61c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
62c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/inventory", int32_t(0),
63c5b2abe0SLewanczyk, Dawid         std::array<const char *, 1>{
64c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Inventory.Item.Board"});
65c5b2abe0SLewanczyk, Dawid };
66c5b2abe0SLewanczyk, Dawid 
67c5b2abe0SLewanczyk, Dawid /**
68c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
69c5b2abe0SLewanczyk, Dawid  *
70c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
71c5b2abe0SLewanczyk, Dawid  * @param[in] name  Computer system name from request
72c5b2abe0SLewanczyk, Dawid  *
73c5b2abe0SLewanczyk, Dawid  * @return None.
74c5b2abe0SLewanczyk, Dawid  */
75a0803efaSEd Tanous void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
761abe55efSEd Tanous                        const std::string &name)
771abe55efSEd Tanous {
78c5b2abe0SLewanczyk, Dawid     const std::array<const char *, 5> interfaces = {
79c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Inventory.Decorator.Asset",
80c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Inventory.Item.Cpu",
81c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Inventory.Item.Dimm",
82c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Inventory.Item.System",
83c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Common.UUID",
84c5b2abe0SLewanczyk, Dawid     };
8555c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
8655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
87c5b2abe0SLewanczyk, Dawid         [name, aResp{std::move(aResp)}](
88c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
89c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
90*6c34de48SEd Tanous                 std::string,
91*6c34de48SEd Tanous                 std::vector<std::pair<std::string, std::vector<std::string>>>>>
92c5b2abe0SLewanczyk, Dawid                 &subtree) {
931abe55efSEd Tanous             if (ec)
941abe55efSEd Tanous             {
9555c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
96a0803efaSEd Tanous                 aResp->res.result(
97a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
98c5b2abe0SLewanczyk, Dawid                 return;
99c5b2abe0SLewanczyk, Dawid             }
100c5b2abe0SLewanczyk, Dawid             bool foundName = false;
101c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
102*6c34de48SEd Tanous             for (const std::pair<std::string,
103*6c34de48SEd Tanous                                  std::vector<std::pair<
104*6c34de48SEd Tanous                                      std::string, std::vector<std::string>>>>
1051abe55efSEd Tanous                      &object : subtree)
1061abe55efSEd Tanous             {
107c5b2abe0SLewanczyk, Dawid                 const std::string &path = object.first;
10855c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
1091abe55efSEd Tanous                 const std::vector<
1101abe55efSEd Tanous                     std::pair<std::string, std::vector<std::string>>>
111c5b2abe0SLewanczyk, Dawid                     &connectionNames = object.second;
1121abe55efSEd Tanous                 if (connectionNames.size() < 1)
1131abe55efSEd Tanous                 {
114c5b2abe0SLewanczyk, Dawid                     continue;
115c5b2abe0SLewanczyk, Dawid                 }
116c5b2abe0SLewanczyk, Dawid                 // Check if computer system exist
1171abe55efSEd Tanous                 if (boost::ends_with(path, name))
1181abe55efSEd Tanous                 {
119c5b2abe0SLewanczyk, Dawid                     foundName = true;
12055c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Found name: " << name;
121*6c34de48SEd Tanous                     const std::string connectionName = connectionNames[0].first;
12255c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
123c5b2abe0SLewanczyk, Dawid                         [aResp, name(std::string(name))](
124c5b2abe0SLewanczyk, Dawid                             const boost::system::error_code ec,
125*6c34de48SEd Tanous                             const std::vector<std::pair<
126*6c34de48SEd Tanous                                 std::string, VariantType>> &propertiesList) {
1271abe55efSEd Tanous                             if (ec)
1281abe55efSEd Tanous                             {
1291abe55efSEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error: "
1301abe55efSEd Tanous                                                  << ec;
131*6c34de48SEd Tanous                                 aResp->res.result(boost::beast::http::status::
132a0803efaSEd Tanous                                                       internal_server_error);
133c5b2abe0SLewanczyk, Dawid                                 return;
134c5b2abe0SLewanczyk, Dawid                             }
135*6c34de48SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
136c5b2abe0SLewanczyk, Dawid                                              << "properties for system";
1371abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
1381abe55efSEd Tanous                                      &property : propertiesList)
1391abe55efSEd Tanous                             {
140c5b2abe0SLewanczyk, Dawid                                 const std::string *value =
1411abe55efSEd Tanous                                     mapbox::getPtr<const std::string>(
1421abe55efSEd Tanous                                         property.second);
1431abe55efSEd Tanous                                 if (value != nullptr)
1441abe55efSEd Tanous                                 {
1451abe55efSEd Tanous                                     aResp->res.jsonValue[property.first] =
1461abe55efSEd Tanous                                         *value;
147c5b2abe0SLewanczyk, Dawid                                 }
148c5b2abe0SLewanczyk, Dawid                             }
14955c7b7a2SEd Tanous                             aResp->res.jsonValue["Name"] = name;
15055c7b7a2SEd Tanous                             aResp->res.jsonValue["Id"] =
15155c7b7a2SEd Tanous                                 aResp->res.jsonValue["SerialNumber"];
152c5b2abe0SLewanczyk, Dawid                         },
153*6c34de48SEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
154*6c34de48SEd Tanous                         "GetAll",
1551abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
1561abe55efSEd Tanous                 }
1571abe55efSEd Tanous                 else
1581abe55efSEd Tanous                 {
159*6c34de48SEd Tanous                     // This is not system, so check if it's cpu, dimm, UUID or
160*6c34de48SEd Tanous                     // BiosVer
1611abe55efSEd Tanous                     for (auto const &s : connectionNames)
1621abe55efSEd Tanous                     {
1631abe55efSEd Tanous                         for (auto const &i : s.second)
1641abe55efSEd Tanous                         {
1651abe55efSEd Tanous                             if (boost::ends_with(i, "Dimm"))
1661abe55efSEd Tanous                             {
1671abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
1681abe55efSEd Tanous                                     << "Found Dimm, now get it properties.";
16955c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
1701abe55efSEd Tanous                                     [&, aResp](
1711abe55efSEd Tanous                                         const boost::system::error_code ec,
172*6c34de48SEd Tanous                                         const std::vector<
173*6c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
1741abe55efSEd Tanous                                             &properties) {
1751abe55efSEd Tanous                                         if (ec)
1761abe55efSEd Tanous                                         {
1771abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
178*6c34de48SEd Tanous                                                 << "DBUS response error " << ec;
179a0803efaSEd Tanous                                             aResp->res.result(
180a0803efaSEd Tanous                                                 boost::beast::http::status::
181a0803efaSEd Tanous                                                     internal_server_error);
182c5b2abe0SLewanczyk, Dawid                                             return;
183c5b2abe0SLewanczyk, Dawid                                         }
184*6c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
185*6c34de48SEd Tanous                                                          << properties.size()
186c5b2abe0SLewanczyk, Dawid                                                          << "Dimm properties.";
1871abe55efSEd Tanous                                         for (const auto &p : properties)
1881abe55efSEd Tanous                                         {
1891abe55efSEd Tanous                                             if (p.first == "MemorySize")
1901abe55efSEd Tanous                                             {
191c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
1921abe55efSEd Tanous                                                     mapbox::getPtr<
1931abe55efSEd Tanous                                                         const std::string>(
1941abe55efSEd Tanous                                                         p.second);
1951abe55efSEd Tanous                                                 if ((value != nullptr) &&
1961abe55efSEd Tanous                                                     (*value != "NULL"))
1971abe55efSEd Tanous                                                 {
198c5b2abe0SLewanczyk, Dawid                                                     // Remove units char
199c5b2abe0SLewanczyk, Dawid                                                     int32_t unitCoeff;
200*6c34de48SEd Tanous                                                     if (boost::ends_with(*value,
201*6c34de48SEd Tanous                                                                          "MB"))
2021abe55efSEd Tanous                                                     {
203c5b2abe0SLewanczyk, Dawid                                                         unitCoeff = 1000;
2041abe55efSEd Tanous                                                     }
205*6c34de48SEd Tanous                                                     else if (boost::ends_with(
206*6c34de48SEd Tanous                                                                  *value, "KB"))
2071abe55efSEd Tanous                                                     {
208c5b2abe0SLewanczyk, Dawid                                                         unitCoeff = 1000000;
2091abe55efSEd Tanous                                                     }
2101abe55efSEd Tanous                                                     else
2111abe55efSEd Tanous                                                     {
212a434f2bdSEd Tanous                                                         BMCWEB_LOG_ERROR
2131abe55efSEd Tanous                                                             << "Unsupported "
214*6c34de48SEd Tanous                                                                "memory units";
215a0803efaSEd Tanous                                                         aResp->res.result(
216*6c34de48SEd Tanous                                                             boost::beast::http::
217*6c34de48SEd Tanous                                                                 status::
218a0803efaSEd Tanous                                                                     internal_server_error);
219c5b2abe0SLewanczyk, Dawid                                                         return;
220c5b2abe0SLewanczyk, Dawid                                                     }
221c5b2abe0SLewanczyk, Dawid 
2221abe55efSEd Tanous                                                     auto memSize =
2231abe55efSEd Tanous                                                         boost::lexical_cast<
2241abe55efSEd Tanous                                                             int>(value->substr(
225*6c34de48SEd Tanous                                                             0, value->length() -
2261abe55efSEd Tanous                                                                    2));
2271abe55efSEd Tanous                                                     aResp->res.jsonValue
228*6c34de48SEd Tanous                                                         ["TotalSystemMemoryGi"
229*6c34de48SEd Tanous                                                          "B"] +=
230c5b2abe0SLewanczyk, Dawid                                                         memSize * unitCoeff;
2311abe55efSEd Tanous                                                     aResp->res.jsonValue
2321abe55efSEd Tanous                                                         ["MemorySummary"]
233*6c34de48SEd Tanous                                                         ["Status"]["State"] =
2341abe55efSEd Tanous                                                         "Enabled";
235c5b2abe0SLewanczyk, Dawid                                                 }
236c5b2abe0SLewanczyk, Dawid                                             }
237c5b2abe0SLewanczyk, Dawid                                         }
238c5b2abe0SLewanczyk, Dawid                                     },
2391abe55efSEd Tanous                                     s.first, path,
240*6c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
241*6c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Dimm");
2421abe55efSEd Tanous                             }
2431abe55efSEd Tanous                             else if (boost::ends_with(i, "Cpu"))
2441abe55efSEd Tanous                             {
2451abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
2461abe55efSEd Tanous                                     << "Found Cpu, now get it properties.";
247a0803efaSEd Tanous                                 crow::connections::systemBus->async_method_call(
2481abe55efSEd Tanous                                     [&, aResp](
249a0803efaSEd Tanous                                         const boost::system::error_code ec,
250*6c34de48SEd Tanous                                         const std::vector<
251*6c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
2521abe55efSEd Tanous                                             &properties) {
2531abe55efSEd Tanous                                         if (ec)
2541abe55efSEd Tanous                                         {
2551abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
256*6c34de48SEd Tanous                                                 << "DBUS response error " << ec;
257a0803efaSEd Tanous                                             aResp->res.result(
258a0803efaSEd Tanous                                                 boost::beast::http::status::
259a0803efaSEd Tanous                                                     internal_server_error);
260c5b2abe0SLewanczyk, Dawid                                             return;
261c5b2abe0SLewanczyk, Dawid                                         }
262*6c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
263*6c34de48SEd Tanous                                                          << properties.size()
264c5b2abe0SLewanczyk, Dawid                                                          << "Cpu properties.";
2651abe55efSEd Tanous                                         for (const auto &p : properties)
2661abe55efSEd Tanous                                         {
267*6c34de48SEd Tanous                                             if (p.first == "ProcessorFamily")
2681abe55efSEd Tanous                                             {
269a0803efaSEd Tanous                                                 const std::string *value =
2701abe55efSEd Tanous                                                     mapbox::getPtr<
271a0803efaSEd Tanous                                                         const std::string>(
2721abe55efSEd Tanous                                                         p.second);
2731abe55efSEd Tanous                                                 if (value != nullptr)
2741abe55efSEd Tanous                                                 {
2751abe55efSEd Tanous                                                     aResp->res.jsonValue
276a0803efaSEd Tanous                                                         ["ProcessorSummary"]
2771abe55efSEd Tanous                                                         ["Count"] =
278c5b2abe0SLewanczyk, Dawid                                                         aResp->res
2791abe55efSEd Tanous                                                             .jsonValue
280*6c34de48SEd Tanous                                                                 ["ProcessorSumm"
281*6c34de48SEd Tanous                                                                  "ary"]["Count"]
282a0803efaSEd Tanous                                                             .get<int>() +
283c5b2abe0SLewanczyk, Dawid                                                         1;
2841abe55efSEd Tanous                                                     aResp->res.jsonValue
285a0803efaSEd Tanous                                                         ["ProcessorSummary"]
286*6c34de48SEd Tanous                                                         ["Status"]["State"] =
287c5b2abe0SLewanczyk, Dawid                                                         "Enabled";
2881abe55efSEd Tanous                                                     aResp->res.jsonValue
289a0803efaSEd Tanous                                                         ["ProcessorSummary"]
290a0803efaSEd Tanous                                                         ["Model"] = *value;
291c5b2abe0SLewanczyk, Dawid                                                 }
292c5b2abe0SLewanczyk, Dawid                                             }
293c5b2abe0SLewanczyk, Dawid                                         }
294c5b2abe0SLewanczyk, Dawid                                     },
2951abe55efSEd Tanous                                     s.first, path,
296*6c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
297*6c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Cpu");
2981abe55efSEd Tanous                             }
2991abe55efSEd Tanous                             else if (boost::ends_with(i, "UUID"))
3001abe55efSEd Tanous                             {
3011abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
3021abe55efSEd Tanous                                     << "Found UUID, now get it properties.";
30355c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
3041abe55efSEd Tanous                                     [aResp](
3051abe55efSEd Tanous                                         const boost::system::error_code ec,
306*6c34de48SEd Tanous                                         const std::vector<
307*6c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
3081abe55efSEd Tanous                                             &properties) {
3091abe55efSEd Tanous                                         if (ec)
3101abe55efSEd Tanous                                         {
3111abe55efSEd Tanous                                             BMCWEB_LOG_DEBUG
312*6c34de48SEd Tanous                                                 << "DBUS response error " << ec;
313a0803efaSEd Tanous                                             aResp->res.result(
314a0803efaSEd Tanous                                                 boost::beast::http::status::
315a0803efaSEd Tanous                                                     internal_server_error);
316c5b2abe0SLewanczyk, Dawid                                             return;
317c5b2abe0SLewanczyk, Dawid                                         }
318*6c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
319*6c34de48SEd Tanous                                                          << properties.size()
320c5b2abe0SLewanczyk, Dawid                                                          << "UUID properties.";
3211abe55efSEd Tanous                                         for (const std::pair<std::string,
322*6c34de48SEd Tanous                                                              VariantType> &p :
323*6c34de48SEd Tanous                                              properties)
3241abe55efSEd Tanous                                         {
3251abe55efSEd Tanous                                             if (p.first == "BIOSVer")
3261abe55efSEd Tanous                                             {
327c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
3281abe55efSEd Tanous                                                     mapbox::getPtr<
3291abe55efSEd Tanous                                                         const std::string>(
3301abe55efSEd Tanous                                                         p.second);
3311abe55efSEd Tanous                                                 if (value != nullptr)
3321abe55efSEd Tanous                                                 {
3331abe55efSEd Tanous                                                     aResp->res.jsonValue
3341abe55efSEd Tanous                                                         ["BiosVersion"] =
3351abe55efSEd Tanous                                                         *value;
336c5b2abe0SLewanczyk, Dawid                                                 }
337c5b2abe0SLewanczyk, Dawid                                             }
3381abe55efSEd Tanous                                             if (p.first == "UUID")
3391abe55efSEd Tanous                                             {
340c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
3411abe55efSEd Tanous                                                     mapbox::getPtr<
3421abe55efSEd Tanous                                                         const std::string>(
3431abe55efSEd Tanous                                                         p.second);
3441abe55efSEd Tanous                                                 BMCWEB_LOG_DEBUG
3451abe55efSEd Tanous                                                     << "UUID = " << *value
3461abe55efSEd Tanous                                                     << " length "
3471abe55efSEd Tanous                                                     << value->length();
3481abe55efSEd Tanous                                                 if (value != nullptr)
3491abe55efSEd Tanous                                                 {
350*6c34de48SEd Tanous                                                     // Workaround for to short
351*6c34de48SEd Tanous                                                     // return str in smbios demo
352*6c34de48SEd Tanous                                                     // app, 32 bytes are
353*6c34de48SEd Tanous                                                     // described by spec
354*6c34de48SEd Tanous                                                     if (value->length() > 0 &&
355*6c34de48SEd Tanous                                                         value->length() < 32)
3561abe55efSEd Tanous                                                     {
3571abe55efSEd Tanous                                                         std::string
3581abe55efSEd Tanous                                                             correctedValue =
3591abe55efSEd Tanous                                                                 *value;
3601abe55efSEd Tanous                                                         correctedValue.append(
3611abe55efSEd Tanous                                                             32 -
362*6c34de48SEd Tanous                                                                 value->length(),
363c5b2abe0SLewanczyk, Dawid                                                             '0');
364*6c34de48SEd Tanous                                                         value = &correctedValue;
3651abe55efSEd Tanous                                                     }
366*6c34de48SEd Tanous                                                     else if (value->length() ==
3671abe55efSEd Tanous                                                              32)
3681abe55efSEd Tanous                                                     {
369*6c34de48SEd Tanous                                                         aResp->res
370*6c34de48SEd Tanous                                                             .jsonValue["UUID"] =
371*6c34de48SEd Tanous                                                             value->substr(0,
372*6c34de48SEd Tanous                                                                           8) +
3731abe55efSEd Tanous                                                             "-" +
374*6c34de48SEd Tanous                                                             value->substr(8,
375*6c34de48SEd Tanous                                                                           4) +
3761abe55efSEd Tanous                                                             "-" +
377*6c34de48SEd Tanous                                                             value->substr(12,
378*6c34de48SEd Tanous                                                                           4) +
3791abe55efSEd Tanous                                                             "-" +
380*6c34de48SEd Tanous                                                             value->substr(16,
381*6c34de48SEd Tanous                                                                           4) +
3821abe55efSEd Tanous                                                             "-" +
383*6c34de48SEd Tanous                                                             value->substr(20,
384*6c34de48SEd Tanous                                                                           12);
385c5b2abe0SLewanczyk, Dawid                                                     }
386c5b2abe0SLewanczyk, Dawid                                                 }
387c5b2abe0SLewanczyk, Dawid                                             }
388c5b2abe0SLewanczyk, Dawid                                         }
389c5b2abe0SLewanczyk, Dawid                                     },
3901abe55efSEd Tanous                                     s.first, path,
391*6c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
3921abe55efSEd Tanous                                     "xyz.openbmc_project.Common.UUID");
393c5b2abe0SLewanczyk, Dawid                             }
394c5b2abe0SLewanczyk, Dawid                         }
395c5b2abe0SLewanczyk, Dawid                     }
396c5b2abe0SLewanczyk, Dawid                 }
397c5b2abe0SLewanczyk, Dawid             }
3981abe55efSEd Tanous             if (foundName == false)
3991abe55efSEd Tanous             {
400a0803efaSEd Tanous                 aResp->res.result(
401a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
402c5b2abe0SLewanczyk, Dawid             }
403c5b2abe0SLewanczyk, Dawid         },
404c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
405c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
406c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
407c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
408c5b2abe0SLewanczyk, Dawid }
409c5b2abe0SLewanczyk, Dawid 
410c5b2abe0SLewanczyk, Dawid /**
411c5b2abe0SLewanczyk, Dawid  * @brief Retrieves identify led group properties over dbus
412c5b2abe0SLewanczyk, Dawid  *
413c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
414c5b2abe0SLewanczyk, Dawid  * @param[in] callback  Callback for process retrieved data.
415c5b2abe0SLewanczyk, Dawid  *
416c5b2abe0SLewanczyk, Dawid  * @return None.
417c5b2abe0SLewanczyk, Dawid  */
418c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
419a0803efaSEd Tanous void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
4201abe55efSEd Tanous                          CallbackFunc &&callback)
4211abe55efSEd Tanous {
42255c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get led groups";
42355c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
4241abe55efSEd Tanous         [aResp{std::move(aResp)},
4251abe55efSEd Tanous          &callback](const boost::system::error_code &ec,
4261abe55efSEd Tanous                     const ManagedObjectsType &resp) {
4271abe55efSEd Tanous             if (ec)
4281abe55efSEd Tanous             {
42955c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
430a0803efaSEd Tanous                 aResp->res.result(
431a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
432c5b2abe0SLewanczyk, Dawid                 return;
433c5b2abe0SLewanczyk, Dawid             }
434*6c34de48SEd Tanous             BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
4351abe55efSEd Tanous             for (const auto &objPath : resp)
4361abe55efSEd Tanous             {
437c5b2abe0SLewanczyk, Dawid                 const std::string &path = objPath.first;
4381abe55efSEd Tanous                 if (path.rfind("enclosure_identify") != std::string::npos)
4391abe55efSEd Tanous                 {
4401abe55efSEd Tanous                     for (const auto &interface : objPath.second)
4411abe55efSEd Tanous                     {
442*6c34de48SEd Tanous                         if (interface.first == "xyz.openbmc_project.Led.Group")
4431abe55efSEd Tanous                         {
4441abe55efSEd Tanous                             for (const auto &property : interface.second)
4451abe55efSEd Tanous                             {
4461abe55efSEd Tanous                                 if (property.first == "Asserted")
4471abe55efSEd Tanous                                 {
448c5b2abe0SLewanczyk, Dawid                                     const bool *asserted =
4491abe55efSEd Tanous                                         mapbox::getPtr<const bool>(
4501abe55efSEd Tanous                                             property.second);
4511abe55efSEd Tanous                                     if (nullptr != asserted)
4521abe55efSEd Tanous                                     {
453c5b2abe0SLewanczyk, Dawid                                         callback(*asserted, aResp);
4541abe55efSEd Tanous                                     }
4551abe55efSEd Tanous                                     else
4561abe55efSEd Tanous                                     {
457c5b2abe0SLewanczyk, Dawid                                         callback(false, aResp);
458c5b2abe0SLewanczyk, Dawid                                     }
459c5b2abe0SLewanczyk, Dawid                                 }
460c5b2abe0SLewanczyk, Dawid                             }
461c5b2abe0SLewanczyk, Dawid                         }
462c5b2abe0SLewanczyk, Dawid                     }
463c5b2abe0SLewanczyk, Dawid                 }
464c5b2abe0SLewanczyk, Dawid             }
465c5b2abe0SLewanczyk, Dawid         },
466c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.GroupManager",
467*6c34de48SEd Tanous         "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
468*6c34de48SEd Tanous         "GetManagedObjects");
469c5b2abe0SLewanczyk, Dawid }
470c5b2abe0SLewanczyk, Dawid 
471c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
472*6c34de48SEd Tanous void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
4731abe55efSEd Tanous {
47455c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get identify led properties";
47555c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
476*6c34de48SEd Tanous         [aResp{std::move(aResp)}, &callback](const boost::system::error_code ec,
477c5b2abe0SLewanczyk, Dawid                                              const PropertiesType &properties) {
4781abe55efSEd Tanous             if (ec)
4791abe55efSEd Tanous             {
48055c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
481a0803efaSEd Tanous                 aResp->res.result(
482a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
483c5b2abe0SLewanczyk, Dawid                 return;
484c5b2abe0SLewanczyk, Dawid             }
4851abe55efSEd Tanous             BMCWEB_LOG_DEBUG << "Got " << properties.size()
4861abe55efSEd Tanous                              << "led properties.";
487c5b2abe0SLewanczyk, Dawid             std::string output;
4881abe55efSEd Tanous             for (const auto &property : properties)
4891abe55efSEd Tanous             {
4901abe55efSEd Tanous                 if (property.first == "State")
4911abe55efSEd Tanous                 {
492c5b2abe0SLewanczyk, Dawid                     const std::string *s =
49355c7b7a2SEd Tanous                         mapbox::getPtr<std::string>(property.second);
4941abe55efSEd Tanous                     if (nullptr != s)
4951abe55efSEd Tanous                     {
49655c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
497c5b2abe0SLewanczyk, Dawid                         const auto pos = s->rfind('.');
4981abe55efSEd Tanous                         if (pos != std::string::npos)
4991abe55efSEd Tanous                         {
500c5b2abe0SLewanczyk, Dawid                             auto led = s->substr(pos + 1);
5011abe55efSEd Tanous                             for (const std::pair<const char *, const char *>
5021abe55efSEd Tanous                                      &p :
5031abe55efSEd Tanous                                  std::array<
504*6c34de48SEd Tanous                                      std::pair<const char *, const char *>, 3>{
505*6c34de48SEd Tanous                                      {{"On", "Lit"},
506c5b2abe0SLewanczyk, Dawid                                       {"Blink", "Blinking"},
5071abe55efSEd Tanous                                       {"Off", "Off"}}})
5081abe55efSEd Tanous                             {
5091abe55efSEd Tanous                                 if (led == p.first)
5101abe55efSEd Tanous                                 {
511c5b2abe0SLewanczyk, Dawid                                     output = p.second;
512c5b2abe0SLewanczyk, Dawid                                 }
513c5b2abe0SLewanczyk, Dawid                             }
514c5b2abe0SLewanczyk, Dawid                         }
515c5b2abe0SLewanczyk, Dawid                     }
516c5b2abe0SLewanczyk, Dawid                 }
517c5b2abe0SLewanczyk, Dawid             }
518c5b2abe0SLewanczyk, Dawid             callback(output, aResp);
519c5b2abe0SLewanczyk, Dawid         },
520c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.Controller.identify",
521c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/led/physical/identify",
522c5b2abe0SLewanczyk, Dawid         "org.freedesktop.DBus.Properties", "GetAll",
523c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Led.Physical");
524c5b2abe0SLewanczyk, Dawid }
525c5b2abe0SLewanczyk, Dawid 
526c5b2abe0SLewanczyk, Dawid /**
527c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
528c5b2abe0SLewanczyk, Dawid  *
529c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
530c5b2abe0SLewanczyk, Dawid  *
531c5b2abe0SLewanczyk, Dawid  * @return None.
532c5b2abe0SLewanczyk, Dawid  */
533a0803efaSEd Tanous void getHostState(std::shared_ptr<AsyncResp> aResp)
5341abe55efSEd Tanous {
53555c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
53655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
537c5b2abe0SLewanczyk, Dawid         [aResp{std::move(aResp)}](const boost::system::error_code ec,
538c5b2abe0SLewanczyk, Dawid                                   const PropertiesType &properties) {
5391abe55efSEd Tanous             if (ec)
5401abe55efSEd Tanous             {
54155c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
542a0803efaSEd Tanous                 aResp->res.result(
543a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
544c5b2abe0SLewanczyk, Dawid                 return;
545c5b2abe0SLewanczyk, Dawid             }
5461abe55efSEd Tanous             BMCWEB_LOG_DEBUG << "Got " << properties.size()
5471abe55efSEd Tanous                              << "host properties.";
5481abe55efSEd Tanous             for (const auto &property : properties)
5491abe55efSEd Tanous             {
5501abe55efSEd Tanous                 if (property.first == "CurrentHostState")
5511abe55efSEd Tanous                 {
552c5b2abe0SLewanczyk, Dawid                     const std::string *s =
55355c7b7a2SEd Tanous                         mapbox::getPtr<const std::string>(property.second);
55455c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Host state: " << *s;
5551abe55efSEd Tanous                     if (nullptr != s)
5561abe55efSEd Tanous                     {
557c5b2abe0SLewanczyk, Dawid                         const auto pos = s->rfind('.');
5581abe55efSEd Tanous                         if (pos != std::string::npos)
5591abe55efSEd Tanous                         {
560c5b2abe0SLewanczyk, Dawid                             // Verify Host State
5611abe55efSEd Tanous                             if (s->substr(pos + 1) == "Running")
5621abe55efSEd Tanous                             {
56355c7b7a2SEd Tanous                                 aResp->res.jsonValue["PowerState"] = "On";
5641abe55efSEd Tanous                                 aResp->res.jsonValue["Status"]["State"] =
5651abe55efSEd Tanous                                     "Enabled";
5661abe55efSEd Tanous                             }
5671abe55efSEd Tanous                             else
5681abe55efSEd Tanous                             {
56955c7b7a2SEd Tanous                                 aResp->res.jsonValue["PowerState"] = "Off";
5701abe55efSEd Tanous                                 aResp->res.jsonValue["Status"]["State"] =
5711abe55efSEd Tanous                                     "Disabled";
572c5b2abe0SLewanczyk, Dawid                             }
573c5b2abe0SLewanczyk, Dawid                         }
574c5b2abe0SLewanczyk, Dawid                     }
575c5b2abe0SLewanczyk, Dawid                 }
576c5b2abe0SLewanczyk, Dawid             }
577c5b2abe0SLewanczyk, Dawid         },
578*6c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
579c5b2abe0SLewanczyk, Dawid         "org.freedesktop.DBus.Properties", "GetAll",
580c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.State.Host");
581c5b2abe0SLewanczyk, Dawid }
582c5b2abe0SLewanczyk, Dawid 
583c5b2abe0SLewanczyk, Dawid /**
584c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
585c5b2abe0SLewanczyk, Dawid  * Schema
586c5b2abe0SLewanczyk, Dawid  */
5871abe55efSEd Tanous class SystemsCollection : public Node
5881abe55efSEd Tanous {
589c5b2abe0SLewanczyk, Dawid   public:
5901abe55efSEd Tanous     SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
5911abe55efSEd Tanous     {
592c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] =
593c5b2abe0SLewanczyk, Dawid             "#ComputerSystemCollection.ComputerSystemCollection";
594c5b2abe0SLewanczyk, Dawid         Node::json["@odata.id"] = "/redfish/v1/Systems";
595c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
596c5b2abe0SLewanczyk, Dawid             "/redfish/v1/"
597c5b2abe0SLewanczyk, Dawid             "$metadata#ComputerSystemCollection.ComputerSystemCollection";
598c5b2abe0SLewanczyk, Dawid         Node::json["Name"] = "Computer System Collection";
599c5b2abe0SLewanczyk, Dawid 
600c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
601c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
602c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
603c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
604c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
605c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
606c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
607c5b2abe0SLewanczyk, Dawid     }
608c5b2abe0SLewanczyk, Dawid 
609c5b2abe0SLewanczyk, Dawid   private:
610c5b2abe0SLewanczyk, Dawid     /**
611c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
612c5b2abe0SLewanczyk, Dawid      */
61355c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
6141abe55efSEd Tanous                const std::vector<std::string> &params) override
6151abe55efSEd Tanous     {
616c5b2abe0SLewanczyk, Dawid         // Get board list, and call the below callback for JSON preparation
617*6c34de48SEd Tanous         getBaseboardList([&](const bool &success,
6181abe55efSEd Tanous                              const std::vector<std::string> &output) {
6191abe55efSEd Tanous             if (success)
6201abe55efSEd Tanous             {
621c5b2abe0SLewanczyk, Dawid                 // ... prepare json array with appropriate @odata.id links
622c5b2abe0SLewanczyk, Dawid                 nlohmann::json boardArray = nlohmann::json::array();
6231abe55efSEd Tanous                 for (const std::string &boardItem : output)
6241abe55efSEd Tanous                 {
625c5b2abe0SLewanczyk, Dawid                     boardArray.push_back(
626d76323e5SEd Tanous                         {{"@odata.id", "/redfish/v1/Systems/" + boardItem}});
627c5b2abe0SLewanczyk, Dawid                 }
628c5b2abe0SLewanczyk, Dawid                 // Then attach members, count size and return,
629c5b2abe0SLewanczyk, Dawid                 Node::json["Members"] = boardArray;
630c5b2abe0SLewanczyk, Dawid                 Node::json["Members@odata.count"] = boardArray.size();
63155c7b7a2SEd Tanous                 res.jsonValue = Node::json;
6321abe55efSEd Tanous             }
6331abe55efSEd Tanous             else
6341abe55efSEd Tanous             {
635c5b2abe0SLewanczyk, Dawid                 // ... otherwise, return INTERNALL ERROR
636c5b2abe0SLewanczyk, Dawid                 res.result(boost::beast::http::status::internal_server_error);
637c5b2abe0SLewanczyk, Dawid             }
638c5b2abe0SLewanczyk, Dawid             res.end();
639c5b2abe0SLewanczyk, Dawid         });
640c5b2abe0SLewanczyk, Dawid     }
641c5b2abe0SLewanczyk, Dawid };
642c5b2abe0SLewanczyk, Dawid 
643c5b2abe0SLewanczyk, Dawid /**
644c5b2abe0SLewanczyk, Dawid  * Systems override class for delivering ComputerSystems Schema
645c5b2abe0SLewanczyk, Dawid  */
6461abe55efSEd Tanous class Systems : public Node
6471abe55efSEd Tanous {
648c5b2abe0SLewanczyk, Dawid   public:
649c5b2abe0SLewanczyk, Dawid     /*
650c5b2abe0SLewanczyk, Dawid      * Default Constructor
651c5b2abe0SLewanczyk, Dawid      */
6521abe55efSEd Tanous     Systems(CrowApp &app) :
6531abe55efSEd Tanous         Node(app, "/redfish/v1/Systems/<str>/", std::string())
6541abe55efSEd Tanous     {
655c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
656c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
657c5b2abe0SLewanczyk, Dawid             "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
658c5b2abe0SLewanczyk, Dawid         Node::json["SystemType"] = "Physical";
659c5b2abe0SLewanczyk, Dawid         Node::json["Description"] = "Computer System";
660c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideEnabled"] =
661c5b2abe0SLewanczyk, Dawid             "Disabled"; // TODO(Dawid), get real boot data
662c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideTarget"] =
663c5b2abe0SLewanczyk, Dawid             "None"; // TODO(Dawid), get real boot data
664c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideMode"] =
665c5b2abe0SLewanczyk, Dawid             "Legacy"; // TODO(Dawid), get real boot data
6661abe55efSEd Tanous         Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
6671abe55efSEd Tanous             {"None",      "Pxe",       "Hdd", "Cd",
6681abe55efSEd Tanous              "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
6691abe55efSEd Tanous                                                // data
670c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Count"] = int(0);
671c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
672c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
673c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
674c5b2abe0SLewanczyk, Dawid 
675c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
676c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
677c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
678c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
679c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
680c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
681c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
682c5b2abe0SLewanczyk, Dawid     }
683c5b2abe0SLewanczyk, Dawid 
684c5b2abe0SLewanczyk, Dawid   private:
685c5b2abe0SLewanczyk, Dawid     /**
686c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
687c5b2abe0SLewanczyk, Dawid      */
68855c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
6891abe55efSEd Tanous                const std::vector<std::string> &params) override
6901abe55efSEd Tanous     {
691c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
692c5b2abe0SLewanczyk, Dawid         // impossible
6931abe55efSEd Tanous         if (params.size() != 1)
6941abe55efSEd Tanous         {
695c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
696c5b2abe0SLewanczyk, Dawid             res.end();
697c5b2abe0SLewanczyk, Dawid             return;
698c5b2abe0SLewanczyk, Dawid         }
699c5b2abe0SLewanczyk, Dawid 
700c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
701c5b2abe0SLewanczyk, Dawid 
70255c7b7a2SEd Tanous         res.jsonValue = Node::json;
70355c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
704c5b2abe0SLewanczyk, Dawid 
705a0803efaSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
706c5b2abe0SLewanczyk, Dawid 
707*6c34de48SEd Tanous         getLedGroupIdentify(
708a0803efaSEd Tanous             asyncResp,
709a0803efaSEd Tanous             [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
7101abe55efSEd Tanous                 if (asserted)
7111abe55efSEd Tanous                 {
712c5b2abe0SLewanczyk, Dawid                     // If led group is asserted, then another call is needed to
713c5b2abe0SLewanczyk, Dawid                     // get led status
714*6c34de48SEd Tanous                     getLedIdentify(
715a0803efaSEd Tanous                         aResp, [](const std::string &ledStatus,
716a0803efaSEd Tanous                                   const std::shared_ptr<AsyncResp> &aResp) {
7171abe55efSEd Tanous                             if (!ledStatus.empty())
7181abe55efSEd Tanous                             {
7191abe55efSEd Tanous                                 aResp->res.jsonValue["IndicatorLED"] =
7201abe55efSEd Tanous                                     ledStatus;
721c5b2abe0SLewanczyk, Dawid                             }
722c5b2abe0SLewanczyk, Dawid                         });
7231abe55efSEd Tanous                 }
7241abe55efSEd Tanous                 else
7251abe55efSEd Tanous                 {
72655c7b7a2SEd Tanous                     aResp->res.jsonValue["IndicatorLED"] = "Off";
727c5b2abe0SLewanczyk, Dawid                 }
728c5b2abe0SLewanczyk, Dawid             });
729*6c34de48SEd Tanous         getComputerSystem(asyncResp, name);
730*6c34de48SEd Tanous         getHostState(asyncResp);
731c5b2abe0SLewanczyk, Dawid     }
732c5b2abe0SLewanczyk, Dawid 
73355c7b7a2SEd Tanous     void doPatch(crow::Response &res, const crow::Request &req,
7341abe55efSEd Tanous                  const std::vector<std::string> &params) override
7351abe55efSEd Tanous     {
736c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
737c5b2abe0SLewanczyk, Dawid         // impossible
7381abe55efSEd Tanous         if (params.size() != 1)
7391abe55efSEd Tanous         {
740c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
741c5b2abe0SLewanczyk, Dawid             res.end();
742c5b2abe0SLewanczyk, Dawid             return;
743c5b2abe0SLewanczyk, Dawid         }
744c5b2abe0SLewanczyk, Dawid         // Parse JSON request body
745c5b2abe0SLewanczyk, Dawid         nlohmann::json patch;
7461abe55efSEd Tanous         if (!json_util::processJsonFromRequest(res, req, patch))
7471abe55efSEd Tanous         {
748c5b2abe0SLewanczyk, Dawid             return;
749c5b2abe0SLewanczyk, Dawid         }
750c5b2abe0SLewanczyk, Dawid         // Find key with new led value
751c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
752c5b2abe0SLewanczyk, Dawid         const std::string *reqLedState = nullptr;
753c5b2abe0SLewanczyk, Dawid         json_util::Result r = json_util::getString(
754c5b2abe0SLewanczyk, Dawid             "IndicatorLED", patch, reqLedState,
755c5b2abe0SLewanczyk, Dawid             static_cast<int>(json_util::MessageSetting::TYPE_ERROR) |
756c5b2abe0SLewanczyk, Dawid                 static_cast<int>(json_util::MessageSetting::MISSING),
75755c7b7a2SEd Tanous             res.jsonValue, std::string("/" + name + "/IndicatorLED"));
7581abe55efSEd Tanous         if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr))
7591abe55efSEd Tanous         {
760c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::bad_request);
761c5b2abe0SLewanczyk, Dawid             res.end();
762c5b2abe0SLewanczyk, Dawid             return;
763c5b2abe0SLewanczyk, Dawid         }
764c5b2abe0SLewanczyk, Dawid         // Verify key value
765c5b2abe0SLewanczyk, Dawid         std::string dbusLedState;
7661abe55efSEd Tanous         for (const auto &p :
7671abe55efSEd Tanous              boost::container::flat_map<const char *, const char *>{
7681abe55efSEd Tanous                  {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}})
7691abe55efSEd Tanous         {
7701abe55efSEd Tanous             if (*reqLedState == p.second)
7711abe55efSEd Tanous             {
772c5b2abe0SLewanczyk, Dawid                 dbusLedState = p.first;
773c5b2abe0SLewanczyk, Dawid             }
774c5b2abe0SLewanczyk, Dawid         }
775c5b2abe0SLewanczyk, Dawid 
776c5b2abe0SLewanczyk, Dawid         // Update led status
777a0803efaSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
77855c7b7a2SEd Tanous         res.jsonValue = Node::json;
77955c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
780c5b2abe0SLewanczyk, Dawid 
781*6c34de48SEd Tanous         getHostState(asyncResp);
782*6c34de48SEd Tanous         getComputerSystem(asyncResp, name);
783c5b2abe0SLewanczyk, Dawid 
7841abe55efSEd Tanous         if (dbusLedState.empty())
7851abe55efSEd Tanous         {
786c5b2abe0SLewanczyk, Dawid             messages::addMessageToJsonRoot(
78755c7b7a2SEd Tanous                 res.jsonValue,
788c5b2abe0SLewanczyk, Dawid                 messages::propertyValueNotInList(*reqLedState, "IndicatorLED"));
7891abe55efSEd Tanous         }
7901abe55efSEd Tanous         else
7911abe55efSEd Tanous         {
792c5b2abe0SLewanczyk, Dawid             // Update led group
79355c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Update led group.";
79455c7b7a2SEd Tanous             crow::connections::systemBus->async_method_call(
795c5b2abe0SLewanczyk, Dawid                 [&, asyncResp{std::move(asyncResp)}](
796c5b2abe0SLewanczyk, Dawid                     const boost::system::error_code ec) {
7971abe55efSEd Tanous                     if (ec)
7981abe55efSEd Tanous                     {
79955c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
800a0803efaSEd Tanous                         asyncResp->res.result(
801a0803efaSEd Tanous                             boost::beast::http::status::internal_server_error);
802c5b2abe0SLewanczyk, Dawid                         return;
803c5b2abe0SLewanczyk, Dawid                     }
80455c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Led group update done.";
805c5b2abe0SLewanczyk, Dawid                 },
806c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.LED.GroupManager",
807c5b2abe0SLewanczyk, Dawid                 "/xyz/openbmc_project/led/groups/enclosure_identify",
808c5b2abe0SLewanczyk, Dawid                 "org.freedesktop.DBus.Properties", "Set",
809c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Led.Group", "Asserted",
810c5b2abe0SLewanczyk, Dawid                 sdbusplus::message::variant<bool>(
811c5b2abe0SLewanczyk, Dawid                     (dbusLedState == "Off" ? false : true)));
812c5b2abe0SLewanczyk, Dawid             // Update identify led status
81355c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
81455c7b7a2SEd Tanous             crow::connections::systemBus->async_method_call(
815c5b2abe0SLewanczyk, Dawid                 [&, asyncResp{std::move(asyncResp)}](
816c5b2abe0SLewanczyk, Dawid                     const boost::system::error_code ec) {
8171abe55efSEd Tanous                     if (ec)
8181abe55efSEd Tanous                     {
81955c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
820a0803efaSEd Tanous                         asyncResp->res.result(
821a0803efaSEd Tanous                             boost::beast::http::status::internal_server_error);
822c5b2abe0SLewanczyk, Dawid                         return;
823c5b2abe0SLewanczyk, Dawid                     }
82455c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Led state update done.";
82555c7b7a2SEd Tanous                     res.jsonValue["IndicatorLED"] = *reqLedState;
826c5b2abe0SLewanczyk, Dawid                 },
827c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.LED.Controller.identify",
828c5b2abe0SLewanczyk, Dawid                 "/xyz/openbmc_project/led/physical/identify",
829c5b2abe0SLewanczyk, Dawid                 "org.freedesktop.DBus.Properties", "Set",
830c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Led.Physical", "State",
831c5b2abe0SLewanczyk, Dawid                 sdbusplus::message::variant<std::string>(
832c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.Led.Physical.Action." + dbusLedState));
833c5b2abe0SLewanczyk, Dawid         }
834c5b2abe0SLewanczyk, Dawid     }
835c5b2abe0SLewanczyk, Dawid };
836c5b2abe0SLewanczyk, Dawid } // namespace redfish
837