xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision cc340dd933d38095214a0eeb7c1ee77510bd30cd)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
181abe55efSEd Tanous #include "boost/container/flat_map.hpp"
191abe55efSEd Tanous #include "node.hpp"
201abe55efSEd Tanous 
21c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
22c5b2abe0SLewanczyk, Dawid 
231abe55efSEd Tanous namespace redfish
241abe55efSEd Tanous {
25c5b2abe0SLewanczyk, Dawid 
26c5b2abe0SLewanczyk, Dawid /**
27c5b2abe0SLewanczyk, Dawid  * @brief Retrieves computer system properties over dbus
28c5b2abe0SLewanczyk, Dawid  *
29c5b2abe0SLewanczyk, Dawid  * @param[in] aResp Shared pointer for completing asynchronous calls
30c5b2abe0SLewanczyk, Dawid  * @param[in] name  Computer system name from request
31c5b2abe0SLewanczyk, Dawid  *
32c5b2abe0SLewanczyk, Dawid  * @return None.
33c5b2abe0SLewanczyk, Dawid  */
34a0803efaSEd Tanous void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
351abe55efSEd Tanous                        const std::string &name)
361abe55efSEd Tanous {
3755c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get available system components.";
3855c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
39c5b2abe0SLewanczyk, Dawid         [name, aResp{std::move(aResp)}](
40c5b2abe0SLewanczyk, Dawid             const boost::system::error_code ec,
41c5b2abe0SLewanczyk, Dawid             const std::vector<std::pair<
426c34de48SEd Tanous                 std::string,
436c34de48SEd Tanous                 std::vector<std::pair<std::string, std::vector<std::string>>>>>
44c5b2abe0SLewanczyk, Dawid                 &subtree) {
451abe55efSEd Tanous             if (ec)
461abe55efSEd Tanous             {
4755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error";
48a0803efaSEd Tanous                 aResp->res.result(
49a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
50c5b2abe0SLewanczyk, Dawid                 return;
51c5b2abe0SLewanczyk, Dawid             }
52c5b2abe0SLewanczyk, Dawid             bool foundName = false;
53c5b2abe0SLewanczyk, Dawid             // Iterate over all retrieved ObjectPaths.
546c34de48SEd Tanous             for (const std::pair<std::string,
556c34de48SEd Tanous                                  std::vector<std::pair<
566c34de48SEd Tanous                                      std::string, std::vector<std::string>>>>
571abe55efSEd Tanous                      &object : subtree)
581abe55efSEd Tanous             {
59c5b2abe0SLewanczyk, Dawid                 const std::string &path = object.first;
6055c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got path: " << path;
611abe55efSEd Tanous                 const std::vector<
621abe55efSEd Tanous                     std::pair<std::string, std::vector<std::string>>>
63c5b2abe0SLewanczyk, Dawid                     &connectionNames = object.second;
641abe55efSEd Tanous                 if (connectionNames.size() < 1)
651abe55efSEd Tanous                 {
66c5b2abe0SLewanczyk, Dawid                     continue;
67c5b2abe0SLewanczyk, Dawid                 }
68c5b2abe0SLewanczyk, Dawid                 // Check if computer system exist
691abe55efSEd Tanous                 if (boost::ends_with(path, name))
701abe55efSEd Tanous                 {
71c5b2abe0SLewanczyk, Dawid                     foundName = true;
7255c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Found name: " << name;
736c34de48SEd Tanous                     const std::string connectionName = connectionNames[0].first;
7455c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
75c5b2abe0SLewanczyk, Dawid                         [aResp, name(std::string(name))](
76c5b2abe0SLewanczyk, Dawid                             const boost::system::error_code ec,
776c34de48SEd Tanous                             const std::vector<std::pair<
786c34de48SEd Tanous                                 std::string, VariantType>> &propertiesList) {
791abe55efSEd Tanous                             if (ec)
801abe55efSEd Tanous                             {
811abe55efSEd Tanous                                 BMCWEB_LOG_ERROR << "DBUS response error: "
821abe55efSEd Tanous                                                  << ec;
836c34de48SEd Tanous                                 aResp->res.result(boost::beast::http::status::
84a0803efaSEd Tanous                                                       internal_server_error);
85c5b2abe0SLewanczyk, Dawid                                 return;
86c5b2abe0SLewanczyk, Dawid                             }
876c34de48SEd Tanous                             BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
88c5b2abe0SLewanczyk, Dawid                                              << "properties for system";
891abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
901abe55efSEd Tanous                                      &property : propertiesList)
911abe55efSEd Tanous                             {
92c5b2abe0SLewanczyk, Dawid                                 const std::string *value =
931abe55efSEd Tanous                                     mapbox::getPtr<const std::string>(
941abe55efSEd Tanous                                         property.second);
951abe55efSEd Tanous                                 if (value != nullptr)
961abe55efSEd Tanous                                 {
971abe55efSEd Tanous                                     aResp->res.jsonValue[property.first] =
981abe55efSEd Tanous                                         *value;
99c5b2abe0SLewanczyk, Dawid                                 }
100c5b2abe0SLewanczyk, Dawid                             }
10155c7b7a2SEd Tanous                             aResp->res.jsonValue["Name"] = name;
10255c7b7a2SEd Tanous                             aResp->res.jsonValue["Id"] =
10355c7b7a2SEd Tanous                                 aResp->res.jsonValue["SerialNumber"];
104c5b2abe0SLewanczyk, Dawid                         },
1056c34de48SEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
1066c34de48SEd Tanous                         "GetAll",
1071abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
1081abe55efSEd Tanous                 }
1091abe55efSEd Tanous                 else
1101abe55efSEd Tanous                 {
1116c34de48SEd Tanous                     // This is not system, so check if it's cpu, dimm, UUID or
1126c34de48SEd Tanous                     // BiosVer
1131abe55efSEd Tanous                     for (auto const &s : connectionNames)
1141abe55efSEd Tanous                     {
1151abe55efSEd Tanous                         for (auto const &i : s.second)
1161abe55efSEd Tanous                         {
1171abe55efSEd Tanous                             if (boost::ends_with(i, "Dimm"))
1181abe55efSEd Tanous                             {
1191abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
1201abe55efSEd Tanous                                     << "Found Dimm, now get it 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.";
1391abe55efSEd Tanous                                         for (const auto &p : properties)
1401abe55efSEd Tanous                                         {
1411abe55efSEd Tanous                                             if (p.first == "MemorySize")
1421abe55efSEd Tanous                                             {
143c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
1441abe55efSEd Tanous                                                     mapbox::getPtr<
1451abe55efSEd Tanous                                                         const std::string>(
1461abe55efSEd Tanous                                                         p.second);
1471abe55efSEd Tanous                                                 if ((value != nullptr) &&
1481abe55efSEd Tanous                                                     (*value != "NULL"))
1491abe55efSEd Tanous                                                 {
150c5b2abe0SLewanczyk, Dawid                                                     // Remove units char
151c5b2abe0SLewanczyk, Dawid                                                     int32_t unitCoeff;
1526c34de48SEd Tanous                                                     if (boost::ends_with(*value,
1536c34de48SEd Tanous                                                                          "MB"))
1541abe55efSEd Tanous                                                     {
155c5b2abe0SLewanczyk, Dawid                                                         unitCoeff = 1000;
1561abe55efSEd Tanous                                                     }
1576c34de48SEd Tanous                                                     else if (boost::ends_with(
1586c34de48SEd Tanous                                                                  *value, "KB"))
1591abe55efSEd Tanous                                                     {
160c5b2abe0SLewanczyk, Dawid                                                         unitCoeff = 1000000;
1611abe55efSEd Tanous                                                     }
1621abe55efSEd Tanous                                                     else
1631abe55efSEd Tanous                                                     {
164a434f2bdSEd Tanous                                                         BMCWEB_LOG_ERROR
1651abe55efSEd Tanous                                                             << "Unsupported "
1666c34de48SEd Tanous                                                                "memory units";
167a0803efaSEd Tanous                                                         aResp->res.result(
1686c34de48SEd Tanous                                                             boost::beast::http::
1696c34de48SEd Tanous                                                                 status::
170a0803efaSEd Tanous                                                                     internal_server_error);
171c5b2abe0SLewanczyk, Dawid                                                         return;
172c5b2abe0SLewanczyk, Dawid                                                     }
173c5b2abe0SLewanczyk, Dawid 
1741abe55efSEd Tanous                                                     auto memSize =
1751abe55efSEd Tanous                                                         boost::lexical_cast<
1761abe55efSEd Tanous                                                             int>(value->substr(
1776c34de48SEd Tanous                                                             0, value->length() -
1781abe55efSEd Tanous                                                                    2));
1791abe55efSEd Tanous                                                     aResp->res.jsonValue
1806c34de48SEd Tanous                                                         ["TotalSystemMemoryGi"
1816c34de48SEd Tanous                                                          "B"] +=
182c5b2abe0SLewanczyk, Dawid                                                         memSize * unitCoeff;
1831abe55efSEd Tanous                                                     aResp->res.jsonValue
1841abe55efSEd Tanous                                                         ["MemorySummary"]
1856c34de48SEd Tanous                                                         ["Status"]["State"] =
1861abe55efSEd Tanous                                                         "Enabled";
187c5b2abe0SLewanczyk, Dawid                                                 }
188c5b2abe0SLewanczyk, Dawid                                             }
189c5b2abe0SLewanczyk, Dawid                                         }
190c5b2abe0SLewanczyk, Dawid                                     },
1911abe55efSEd Tanous                                     s.first, path,
1926c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
1936c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Dimm");
1941abe55efSEd Tanous                             }
1951abe55efSEd Tanous                             else if (boost::ends_with(i, "Cpu"))
1961abe55efSEd Tanous                             {
1971abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
1981abe55efSEd Tanous                                     << "Found Cpu, now get it properties.";
199a0803efaSEd Tanous                                 crow::connections::systemBus->async_method_call(
2006617338dSEd Tanous                                     [aResp](
201a0803efaSEd Tanous                                         const boost::system::error_code ec,
2026c34de48SEd Tanous                                         const std::vector<
2036c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
2041abe55efSEd Tanous                                             &properties) {
2051abe55efSEd Tanous                                         if (ec)
2061abe55efSEd Tanous                                         {
2071abe55efSEd Tanous                                             BMCWEB_LOG_ERROR
2086c34de48SEd Tanous                                                 << "DBUS response error " << ec;
209a0803efaSEd Tanous                                             aResp->res.result(
210a0803efaSEd Tanous                                                 boost::beast::http::status::
211a0803efaSEd Tanous                                                     internal_server_error);
212c5b2abe0SLewanczyk, Dawid                                             return;
213c5b2abe0SLewanczyk, Dawid                                         }
2146c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
2156c34de48SEd Tanous                                                          << properties.size()
216c5b2abe0SLewanczyk, Dawid                                                          << "Cpu properties.";
2171abe55efSEd Tanous                                         for (const auto &p : properties)
2181abe55efSEd Tanous                                         {
2196c34de48SEd Tanous                                             if (p.first == "ProcessorFamily")
2201abe55efSEd Tanous                                             {
221a0803efaSEd Tanous                                                 const std::string *value =
2221abe55efSEd Tanous                                                     mapbox::getPtr<
223a0803efaSEd Tanous                                                         const std::string>(
2241abe55efSEd Tanous                                                         p.second);
2251abe55efSEd Tanous                                                 if (value != nullptr)
2261abe55efSEd Tanous                                                 {
2271abe55efSEd Tanous                                                     aResp->res.jsonValue
228a0803efaSEd Tanous                                                         ["ProcessorSummary"]
2291abe55efSEd Tanous                                                         ["Count"] =
230c5b2abe0SLewanczyk, Dawid                                                         aResp->res
2311abe55efSEd Tanous                                                             .jsonValue
2326c34de48SEd Tanous                                                                 ["ProcessorSumm"
2336c34de48SEd Tanous                                                                  "ary"]["Count"]
234a0803efaSEd Tanous                                                             .get<int>() +
235c5b2abe0SLewanczyk, Dawid                                                         1;
2361abe55efSEd Tanous                                                     aResp->res.jsonValue
237a0803efaSEd Tanous                                                         ["ProcessorSummary"]
2386c34de48SEd Tanous                                                         ["Status"]["State"] =
239c5b2abe0SLewanczyk, Dawid                                                         "Enabled";
2401abe55efSEd Tanous                                                     aResp->res.jsonValue
241a0803efaSEd Tanous                                                         ["ProcessorSummary"]
242a0803efaSEd Tanous                                                         ["Model"] = *value;
243c5b2abe0SLewanczyk, Dawid                                                 }
244c5b2abe0SLewanczyk, Dawid                                             }
245c5b2abe0SLewanczyk, Dawid                                         }
246c5b2abe0SLewanczyk, Dawid                                     },
2471abe55efSEd Tanous                                     s.first, path,
2486c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
2496c34de48SEd Tanous                                     "xyz.openbmc_project.Inventory.Item.Cpu");
2501abe55efSEd Tanous                             }
2511abe55efSEd Tanous                             else if (boost::ends_with(i, "UUID"))
2521abe55efSEd Tanous                             {
2531abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG
2541abe55efSEd Tanous                                     << "Found UUID, now get it properties.";
25555c7b7a2SEd Tanous                                 crow::connections::systemBus->async_method_call(
2561abe55efSEd Tanous                                     [aResp](
2571abe55efSEd Tanous                                         const boost::system::error_code ec,
2586c34de48SEd Tanous                                         const std::vector<
2596c34de48SEd Tanous                                             std::pair<std::string, VariantType>>
2601abe55efSEd Tanous                                             &properties) {
2611abe55efSEd Tanous                                         if (ec)
2621abe55efSEd Tanous                                         {
2631abe55efSEd Tanous                                             BMCWEB_LOG_DEBUG
2646c34de48SEd Tanous                                                 << "DBUS response error " << ec;
265a0803efaSEd Tanous                                             aResp->res.result(
266a0803efaSEd Tanous                                                 boost::beast::http::status::
267a0803efaSEd Tanous                                                     internal_server_error);
268c5b2abe0SLewanczyk, Dawid                                             return;
269c5b2abe0SLewanczyk, Dawid                                         }
2706c34de48SEd Tanous                                         BMCWEB_LOG_DEBUG << "Got "
2716c34de48SEd Tanous                                                          << properties.size()
272c5b2abe0SLewanczyk, Dawid                                                          << "UUID properties.";
2731abe55efSEd Tanous                                         for (const std::pair<std::string,
2746c34de48SEd Tanous                                                              VariantType> &p :
2756c34de48SEd Tanous                                              properties)
2761abe55efSEd Tanous                                         {
2771abe55efSEd Tanous                                             if (p.first == "BIOSVer")
2781abe55efSEd Tanous                                             {
279c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
2801abe55efSEd Tanous                                                     mapbox::getPtr<
2811abe55efSEd Tanous                                                         const std::string>(
2821abe55efSEd Tanous                                                         p.second);
2831abe55efSEd Tanous                                                 if (value != nullptr)
2841abe55efSEd Tanous                                                 {
2851abe55efSEd Tanous                                                     aResp->res.jsonValue
2861abe55efSEd Tanous                                                         ["BiosVersion"] =
2871abe55efSEd Tanous                                                         *value;
288c5b2abe0SLewanczyk, Dawid                                                 }
289c5b2abe0SLewanczyk, Dawid                                             }
2901abe55efSEd Tanous                                             if (p.first == "UUID")
2911abe55efSEd Tanous                                             {
292c5b2abe0SLewanczyk, Dawid                                                 const std::string *value =
2931abe55efSEd Tanous                                                     mapbox::getPtr<
2941abe55efSEd Tanous                                                         const std::string>(
2951abe55efSEd Tanous                                                         p.second);
2961abe55efSEd Tanous                                                 BMCWEB_LOG_DEBUG
2971abe55efSEd Tanous                                                     << "UUID = " << *value
2981abe55efSEd Tanous                                                     << " length "
2991abe55efSEd Tanous                                                     << value->length();
3001abe55efSEd Tanous                                                 if (value != nullptr)
3011abe55efSEd Tanous                                                 {
3026c34de48SEd Tanous                                                     // Workaround for to short
3036c34de48SEd Tanous                                                     // return str in smbios demo
3046c34de48SEd Tanous                                                     // app, 32 bytes are
3056c34de48SEd Tanous                                                     // described by spec
3066c34de48SEd Tanous                                                     if (value->length() > 0 &&
3076c34de48SEd Tanous                                                         value->length() < 32)
3081abe55efSEd Tanous                                                     {
3091abe55efSEd Tanous                                                         std::string
3101abe55efSEd Tanous                                                             correctedValue =
3111abe55efSEd Tanous                                                                 *value;
3121abe55efSEd Tanous                                                         correctedValue.append(
3131abe55efSEd Tanous                                                             32 -
3146c34de48SEd Tanous                                                                 value->length(),
315c5b2abe0SLewanczyk, Dawid                                                             '0');
3166c34de48SEd Tanous                                                         value = &correctedValue;
3171abe55efSEd Tanous                                                     }
3186c34de48SEd Tanous                                                     else if (value->length() ==
3191abe55efSEd Tanous                                                              32)
3201abe55efSEd Tanous                                                     {
3216c34de48SEd Tanous                                                         aResp->res
3226c34de48SEd Tanous                                                             .jsonValue["UUID"] =
3236c34de48SEd Tanous                                                             value->substr(0,
3246c34de48SEd Tanous                                                                           8) +
3251abe55efSEd Tanous                                                             "-" +
3266c34de48SEd Tanous                                                             value->substr(8,
3276c34de48SEd Tanous                                                                           4) +
3281abe55efSEd Tanous                                                             "-" +
3296c34de48SEd Tanous                                                             value->substr(12,
3306c34de48SEd Tanous                                                                           4) +
3311abe55efSEd Tanous                                                             "-" +
3326c34de48SEd Tanous                                                             value->substr(16,
3336c34de48SEd Tanous                                                                           4) +
3341abe55efSEd Tanous                                                             "-" +
3356c34de48SEd Tanous                                                             value->substr(20,
3366c34de48SEd Tanous                                                                           12);
337c5b2abe0SLewanczyk, Dawid                                                     }
338c5b2abe0SLewanczyk, Dawid                                                 }
339c5b2abe0SLewanczyk, Dawid                                             }
340c5b2abe0SLewanczyk, Dawid                                         }
341c5b2abe0SLewanczyk, Dawid                                     },
3421abe55efSEd Tanous                                     s.first, path,
3436c34de48SEd Tanous                                     "org.freedesktop.DBus.Properties", "GetAll",
3441abe55efSEd Tanous                                     "xyz.openbmc_project.Common.UUID");
345c5b2abe0SLewanczyk, Dawid                             }
346c5b2abe0SLewanczyk, Dawid                         }
347c5b2abe0SLewanczyk, Dawid                     }
348c5b2abe0SLewanczyk, Dawid                 }
349c5b2abe0SLewanczyk, Dawid             }
3501abe55efSEd Tanous             if (foundName == false)
3511abe55efSEd Tanous             {
352a0803efaSEd Tanous                 aResp->res.result(
353a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
354c5b2abe0SLewanczyk, Dawid             }
355c5b2abe0SLewanczyk, Dawid         },
356c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper",
357c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/object_mapper",
358c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.ObjectMapper", "GetSubTree",
3596617338dSEd Tanous         "/xyz/openbmc_project/inventory", int32_t(0),
3606617338dSEd Tanous         std::array<const char *, 5>{
3616617338dSEd Tanous             "xyz.openbmc_project.Inventory.Decorator.Asset",
3626617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Cpu",
3636617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.Dimm",
3646617338dSEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
3656617338dSEd Tanous             "xyz.openbmc_project.Common.UUID",
3666617338dSEd Tanous         });
367c5b2abe0SLewanczyk, Dawid }
368c5b2abe0SLewanczyk, Dawid 
369c5b2abe0SLewanczyk, Dawid /**
370c5b2abe0SLewanczyk, Dawid  * @brief Retrieves identify led group properties over dbus
371c5b2abe0SLewanczyk, Dawid  *
372c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
373c5b2abe0SLewanczyk, Dawid  * @param[in] callback  Callback for process retrieved data.
374c5b2abe0SLewanczyk, Dawid  *
375c5b2abe0SLewanczyk, Dawid  * @return None.
376c5b2abe0SLewanczyk, Dawid  */
377c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
378a0803efaSEd Tanous void getLedGroupIdentify(std::shared_ptr<AsyncResp> aResp,
3791abe55efSEd Tanous                          CallbackFunc &&callback)
3801abe55efSEd Tanous {
38155c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get led groups";
38255c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
3831abe55efSEd Tanous         [aResp{std::move(aResp)},
3846617338dSEd Tanous          callback{std::move(callback)}](const boost::system::error_code &ec,
3851abe55efSEd Tanous                                         const ManagedObjectsType &resp) {
3861abe55efSEd Tanous             if (ec)
3871abe55efSEd Tanous             {
38855c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
389a0803efaSEd Tanous                 aResp->res.result(
390a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
391c5b2abe0SLewanczyk, Dawid                 return;
392c5b2abe0SLewanczyk, Dawid             }
3936c34de48SEd Tanous             BMCWEB_LOG_DEBUG << "Got " << resp.size() << "led group objects.";
3941abe55efSEd Tanous             for (const auto &objPath : resp)
3951abe55efSEd Tanous             {
396c5b2abe0SLewanczyk, Dawid                 const std::string &path = objPath.first;
3971abe55efSEd Tanous                 if (path.rfind("enclosure_identify") != std::string::npos)
3981abe55efSEd Tanous                 {
3991abe55efSEd Tanous                     for (const auto &interface : objPath.second)
4001abe55efSEd Tanous                     {
4016c34de48SEd Tanous                         if (interface.first == "xyz.openbmc_project.Led.Group")
4021abe55efSEd Tanous                         {
4031abe55efSEd Tanous                             for (const auto &property : interface.second)
4041abe55efSEd Tanous                             {
4051abe55efSEd Tanous                                 if (property.first == "Asserted")
4061abe55efSEd Tanous                                 {
407c5b2abe0SLewanczyk, Dawid                                     const bool *asserted =
4081abe55efSEd Tanous                                         mapbox::getPtr<const bool>(
4091abe55efSEd Tanous                                             property.second);
4101abe55efSEd Tanous                                     if (nullptr != asserted)
4111abe55efSEd Tanous                                     {
412c5b2abe0SLewanczyk, Dawid                                         callback(*asserted, aResp);
4131abe55efSEd Tanous                                     }
4141abe55efSEd Tanous                                     else
4151abe55efSEd Tanous                                     {
416c5b2abe0SLewanczyk, Dawid                                         callback(false, aResp);
417c5b2abe0SLewanczyk, Dawid                                     }
418c5b2abe0SLewanczyk, Dawid                                 }
419c5b2abe0SLewanczyk, Dawid                             }
420c5b2abe0SLewanczyk, Dawid                         }
421c5b2abe0SLewanczyk, Dawid                     }
422c5b2abe0SLewanczyk, Dawid                 }
423c5b2abe0SLewanczyk, Dawid             }
424c5b2abe0SLewanczyk, Dawid         },
425c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.GroupManager",
4266c34de48SEd Tanous         "/xyz/openbmc_project/led/groups", "org.freedesktop.DBus.ObjectManager",
4276c34de48SEd Tanous         "GetManagedObjects");
428c5b2abe0SLewanczyk, Dawid }
429c5b2abe0SLewanczyk, Dawid 
430c5b2abe0SLewanczyk, Dawid template <typename CallbackFunc>
4316c34de48SEd Tanous void getLedIdentify(std::shared_ptr<AsyncResp> aResp, CallbackFunc &&callback)
4321abe55efSEd Tanous {
43355c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get identify led properties";
43455c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
4356617338dSEd Tanous         [aResp,
4366617338dSEd Tanous          callback{std::move(callback)}](const boost::system::error_code ec,
437c5b2abe0SLewanczyk, Dawid                                         const PropertiesType &properties) {
4381abe55efSEd Tanous             if (ec)
4391abe55efSEd Tanous             {
44055c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
441a0803efaSEd Tanous                 aResp->res.result(
442a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
443c5b2abe0SLewanczyk, Dawid                 return;
444c5b2abe0SLewanczyk, Dawid             }
4451abe55efSEd Tanous             BMCWEB_LOG_DEBUG << "Got " << properties.size()
4461abe55efSEd Tanous                              << "led properties.";
447c5b2abe0SLewanczyk, Dawid             std::string output;
4481abe55efSEd Tanous             for (const auto &property : properties)
4491abe55efSEd Tanous             {
4501abe55efSEd Tanous                 if (property.first == "State")
4511abe55efSEd Tanous                 {
452c5b2abe0SLewanczyk, Dawid                     const std::string *s =
45355c7b7a2SEd Tanous                         mapbox::getPtr<std::string>(property.second);
4541abe55efSEd Tanous                     if (nullptr != s)
4551abe55efSEd Tanous                     {
45655c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
457c5b2abe0SLewanczyk, Dawid                         const auto pos = s->rfind('.');
4581abe55efSEd Tanous                         if (pos != std::string::npos)
4591abe55efSEd Tanous                         {
460c5b2abe0SLewanczyk, Dawid                             auto led = s->substr(pos + 1);
4611abe55efSEd Tanous                             for (const std::pair<const char *, const char *>
4621abe55efSEd Tanous                                      &p :
4631abe55efSEd Tanous                                  std::array<
4646c34de48SEd Tanous                                      std::pair<const char *, const char *>, 3>{
4656c34de48SEd Tanous                                      {{"On", "Lit"},
466c5b2abe0SLewanczyk, Dawid                                       {"Blink", "Blinking"},
4671abe55efSEd Tanous                                       {"Off", "Off"}}})
4681abe55efSEd Tanous                             {
4691abe55efSEd Tanous                                 if (led == p.first)
4701abe55efSEd Tanous                                 {
471c5b2abe0SLewanczyk, Dawid                                     output = p.second;
472c5b2abe0SLewanczyk, Dawid                                 }
473c5b2abe0SLewanczyk, Dawid                             }
474c5b2abe0SLewanczyk, Dawid                         }
475c5b2abe0SLewanczyk, Dawid                     }
476c5b2abe0SLewanczyk, Dawid                 }
477c5b2abe0SLewanczyk, Dawid             }
478c5b2abe0SLewanczyk, Dawid             callback(output, aResp);
479c5b2abe0SLewanczyk, Dawid         },
480c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.LED.Controller.identify",
481c5b2abe0SLewanczyk, Dawid         "/xyz/openbmc_project/led/physical/identify",
482c5b2abe0SLewanczyk, Dawid         "org.freedesktop.DBus.Properties", "GetAll",
483c5b2abe0SLewanczyk, Dawid         "xyz.openbmc_project.Led.Physical");
484c5b2abe0SLewanczyk, Dawid }
485c5b2abe0SLewanczyk, Dawid 
486c5b2abe0SLewanczyk, Dawid /**
487c5b2abe0SLewanczyk, Dawid  * @brief Retrieves host state properties over dbus
488c5b2abe0SLewanczyk, Dawid  *
489c5b2abe0SLewanczyk, Dawid  * @param[in] aResp     Shared pointer for completing asynchronous calls.
490c5b2abe0SLewanczyk, Dawid  *
491c5b2abe0SLewanczyk, Dawid  * @return None.
492c5b2abe0SLewanczyk, Dawid  */
493a0803efaSEd Tanous void getHostState(std::shared_ptr<AsyncResp> aResp)
4941abe55efSEd Tanous {
49555c7b7a2SEd Tanous     BMCWEB_LOG_DEBUG << "Get host information.";
49655c7b7a2SEd Tanous     crow::connections::systemBus->async_method_call(
4976617338dSEd Tanous         [aResp{std::move(aResp)}](
4986617338dSEd Tanous             const boost::system::error_code ec,
4996617338dSEd Tanous             const sdbusplus::message::variant<std::string> &hostState) {
5001abe55efSEd Tanous             if (ec)
5011abe55efSEd Tanous             {
50255c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
503a0803efaSEd Tanous                 aResp->res.result(
504a0803efaSEd Tanous                     boost::beast::http::status::internal_server_error);
505c5b2abe0SLewanczyk, Dawid                 return;
506c5b2abe0SLewanczyk, Dawid             }
5076617338dSEd Tanous 
5086617338dSEd Tanous             const std::string *s = mapbox::getPtr<const std::string>(hostState);
50955c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Host state: " << *s;
5106617338dSEd Tanous             if (s != nullptr)
5111abe55efSEd Tanous             {
512c5b2abe0SLewanczyk, Dawid                 // Verify Host State
5136617338dSEd Tanous                 if (*s == "xyz.openbmc_project.State.Host.Running")
5141abe55efSEd Tanous                 {
51555c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "On";
5166617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Enabled";
5171abe55efSEd Tanous                 }
5181abe55efSEd Tanous                 else
5191abe55efSEd Tanous                 {
52055c7b7a2SEd Tanous                     aResp->res.jsonValue["PowerState"] = "Off";
5216617338dSEd Tanous                     aResp->res.jsonValue["Status"]["State"] = "Disabled";
522c5b2abe0SLewanczyk, Dawid                 }
523c5b2abe0SLewanczyk, Dawid             }
524c5b2abe0SLewanczyk, Dawid         },
5256c34de48SEd Tanous         "xyz.openbmc_project.State.Host", "/xyz/openbmc_project/state/host0",
5266617338dSEd Tanous         "org.freedesktop.DBus.Properties", "Get",
5276617338dSEd Tanous         "xyz.openbmc_project.State.Host", "CurrentHostState");
528c5b2abe0SLewanczyk, Dawid }
529c5b2abe0SLewanczyk, Dawid 
530c5b2abe0SLewanczyk, Dawid /**
531c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
532c5b2abe0SLewanczyk, Dawid  * Schema
533c5b2abe0SLewanczyk, Dawid  */
5341abe55efSEd Tanous class SystemsCollection : public Node
5351abe55efSEd Tanous {
536c5b2abe0SLewanczyk, Dawid   public:
5371abe55efSEd Tanous     SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
5381abe55efSEd Tanous     {
539c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] =
540c5b2abe0SLewanczyk, Dawid             "#ComputerSystemCollection.ComputerSystemCollection";
541c5b2abe0SLewanczyk, Dawid         Node::json["@odata.id"] = "/redfish/v1/Systems";
542c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
543c5b2abe0SLewanczyk, Dawid             "/redfish/v1/"
544c5b2abe0SLewanczyk, Dawid             "$metadata#ComputerSystemCollection.ComputerSystemCollection";
545c5b2abe0SLewanczyk, Dawid         Node::json["Name"] = "Computer System Collection";
546c5b2abe0SLewanczyk, Dawid 
547c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
548c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
549c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
550c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
551c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
552c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
553c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
554c5b2abe0SLewanczyk, Dawid     }
555c5b2abe0SLewanczyk, Dawid 
556c5b2abe0SLewanczyk, Dawid   private:
55755c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
5581abe55efSEd Tanous                const std::vector<std::string> &params) override
5591abe55efSEd Tanous     {
5606617338dSEd Tanous         BMCWEB_LOG_DEBUG << "Get list of available boards.";
5616617338dSEd Tanous         std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
5626617338dSEd Tanous         res.jsonValue = Node::json;
5636617338dSEd Tanous         crow::connections::systemBus->async_method_call(
5646617338dSEd Tanous             [asyncResp](const boost::system::error_code ec,
5656617338dSEd Tanous                         const std::vector<std::string> &resp) {
5666617338dSEd Tanous                 if (ec)
5671abe55efSEd Tanous                 {
5686617338dSEd Tanous                     asyncResp->res.result(
5696617338dSEd Tanous                         boost::beast::http::status::internal_server_error);
5706617338dSEd Tanous                     return;
5716617338dSEd Tanous                 }
5726617338dSEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
5736617338dSEd Tanous 
574c5b2abe0SLewanczyk, Dawid                 // ... prepare json array with appropriate @odata.id links
5756617338dSEd Tanous                 nlohmann::json &boardArray =
5766617338dSEd Tanous                     asyncResp->res.jsonValue["Members"];
5776617338dSEd Tanous                 boardArray = nlohmann::json::array();
5786617338dSEd Tanous 
5796617338dSEd Tanous                 // Iterate over all retrieved ObjectPaths.
5806617338dSEd Tanous                 for (const std::string &objpath : resp)
5816617338dSEd Tanous                 {
5826617338dSEd Tanous                     std::size_t lastPos = objpath.rfind("/");
5836617338dSEd Tanous                     if (lastPos != std::string::npos)
5841abe55efSEd Tanous                     {
585c5b2abe0SLewanczyk, Dawid                         boardArray.push_back(
5866617338dSEd Tanous                             {{"@odata.id", "/redfish/v1/Systems/" +
5876617338dSEd Tanous                                                objpath.substr(lastPos + 1)}});
588c5b2abe0SLewanczyk, Dawid                     }
5891abe55efSEd Tanous                 }
5906617338dSEd Tanous 
5916617338dSEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] =
5926617338dSEd Tanous                     boardArray.size();
5936617338dSEd Tanous             },
5946617338dSEd Tanous             "xyz.openbmc_project.ObjectMapper",
5956617338dSEd Tanous             "/xyz/openbmc_project/object_mapper",
5966617338dSEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
5976617338dSEd Tanous             "/xyz/openbmc_project/inventory", int32_t(0),
5986617338dSEd Tanous             std::array<const char *, 1>{
5996617338dSEd Tanous                 "xyz.openbmc_project.Inventory.Item.Board"});
600c5b2abe0SLewanczyk, Dawid     }
601c5b2abe0SLewanczyk, Dawid };
602c5b2abe0SLewanczyk, Dawid 
603c5b2abe0SLewanczyk, Dawid /**
604*cc340dd9SEd Tanous  * SystemActionsReset class supports handle POST method for Reset action.
605*cc340dd9SEd Tanous  * The class retrieves and sends data directly to D-Bus.
606*cc340dd9SEd Tanous  */
607*cc340dd9SEd Tanous class SystemActionsReset : public Node
608*cc340dd9SEd Tanous {
609*cc340dd9SEd Tanous   public:
610*cc340dd9SEd Tanous     SystemActionsReset(CrowApp &app) :
611*cc340dd9SEd Tanous         Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
612*cc340dd9SEd Tanous              std::string())
613*cc340dd9SEd Tanous     {
614*cc340dd9SEd Tanous         entityPrivileges = {
615*cc340dd9SEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
616*cc340dd9SEd Tanous     }
617*cc340dd9SEd Tanous 
618*cc340dd9SEd Tanous   private:
619*cc340dd9SEd Tanous     /**
620*cc340dd9SEd Tanous      * Function handles POST method request.
621*cc340dd9SEd Tanous      * Analyzes POST body message before sends Reset request data to D-Bus.
622*cc340dd9SEd Tanous      */
623*cc340dd9SEd Tanous     void doPost(crow::Response &res, const crow::Request &req,
624*cc340dd9SEd Tanous                 const std::vector<std::string> &params) override
625*cc340dd9SEd Tanous     {
626*cc340dd9SEd Tanous         // Parse JSON request body.
627*cc340dd9SEd Tanous         nlohmann::json post;
628*cc340dd9SEd Tanous         if (!json_util::processJsonFromRequest(res, req, post))
629*cc340dd9SEd Tanous         {
630*cc340dd9SEd Tanous             return;
631*cc340dd9SEd Tanous         }
632*cc340dd9SEd Tanous 
633*cc340dd9SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
634*cc340dd9SEd Tanous 
635*cc340dd9SEd Tanous         for (const auto &item : post.items())
636*cc340dd9SEd Tanous         {
637*cc340dd9SEd Tanous             if (item.key() == "ResetType")
638*cc340dd9SEd Tanous             {
639*cc340dd9SEd Tanous                 const std::string *reqResetType =
640*cc340dd9SEd Tanous                     item.value().get_ptr<const std::string *>();
641*cc340dd9SEd Tanous                 if (reqResetType == nullptr)
642*cc340dd9SEd Tanous                 {
643*cc340dd9SEd Tanous                     res.result(boost::beast::http::status::bad_request);
644*cc340dd9SEd Tanous                     messages::addMessageToErrorJson(
645*cc340dd9SEd Tanous                         asyncResp->res.jsonValue,
646*cc340dd9SEd Tanous                         messages::actionParameterValueFormatError(
647*cc340dd9SEd Tanous                             item.value().dump(), "ResetType",
648*cc340dd9SEd Tanous                             "ComputerSystem.Reset"));
649*cc340dd9SEd Tanous                     res.end();
650*cc340dd9SEd Tanous                     return;
651*cc340dd9SEd Tanous                 }
652*cc340dd9SEd Tanous 
653*cc340dd9SEd Tanous                 if (*reqResetType == "ForceOff")
654*cc340dd9SEd Tanous                 {
655*cc340dd9SEd Tanous                     // Force off acts on the chassis
656*cc340dd9SEd Tanous                     crow::connections::systemBus->async_method_call(
657*cc340dd9SEd Tanous                         [asyncResp](const boost::system::error_code ec) {
658*cc340dd9SEd Tanous                             if (ec)
659*cc340dd9SEd Tanous                             {
660*cc340dd9SEd Tanous                                 BMCWEB_LOG_ERROR << "D-Bus responses error: "
661*cc340dd9SEd Tanous                                                  << ec;
662*cc340dd9SEd Tanous                                 asyncResp->res.result(
663*cc340dd9SEd Tanous                                     boost::beast::http::status::
664*cc340dd9SEd Tanous                                         internal_server_error);
665*cc340dd9SEd Tanous                                 return;
666*cc340dd9SEd Tanous                             }
667*cc340dd9SEd Tanous                             // TODO Consider support polling mechanism to verify
668*cc340dd9SEd Tanous                             // status of host and chassis after execute the
669*cc340dd9SEd Tanous                             // requested action.
670*cc340dd9SEd Tanous                             BMCWEB_LOG_DEBUG << "Response with no content";
671*cc340dd9SEd Tanous                             asyncResp->res.result(
672*cc340dd9SEd Tanous                                 boost::beast::http::status::no_content);
673*cc340dd9SEd Tanous                         },
674*cc340dd9SEd Tanous                         "xyz.openbmc_project.State.Chassis",
675*cc340dd9SEd Tanous                         "/xyz/openbmc_project/state/chassis0",
676*cc340dd9SEd Tanous                         "org.freedesktop.DBus.Properties", "Set",
677*cc340dd9SEd Tanous                         "RequestedPowerTransition",
678*cc340dd9SEd Tanous                         "xyz.openbmc_project.State.Chassis",
679*cc340dd9SEd Tanous                         sdbusplus::message::variant<std::string>{
680*cc340dd9SEd Tanous                             "xyz.openbmc_project.State.Chassis.Transition."
681*cc340dd9SEd Tanous                             "Off"});
682*cc340dd9SEd Tanous                     return;
683*cc340dd9SEd Tanous                 }
684*cc340dd9SEd Tanous                 // all other actions operate on the host
685*cc340dd9SEd Tanous                 std::string command;
686*cc340dd9SEd Tanous                 // Execute Reset Action regarding to each reset type.
687*cc340dd9SEd Tanous                 if (*reqResetType == "On")
688*cc340dd9SEd Tanous                 {
689*cc340dd9SEd Tanous                     command = "xyz.openbmc_project.State.Host.Transition.On";
690*cc340dd9SEd Tanous                 }
691*cc340dd9SEd Tanous                 else if (*reqResetType == "GracefulShutdown")
692*cc340dd9SEd Tanous                 {
693*cc340dd9SEd Tanous                     command = "xyz.openbmc_project.State.Host.Transition.Off";
694*cc340dd9SEd Tanous                 }
695*cc340dd9SEd Tanous                 else if (*reqResetType == "GracefulRestart")
696*cc340dd9SEd Tanous                 {
697*cc340dd9SEd Tanous                     command =
698*cc340dd9SEd Tanous                         "xyz.openbmc_project.State.Host.Transition.Reboot";
699*cc340dd9SEd Tanous                 }
700*cc340dd9SEd Tanous                 else
701*cc340dd9SEd Tanous                 {
702*cc340dd9SEd Tanous                     res.result(boost::beast::http::status::bad_request);
703*cc340dd9SEd Tanous                     messages::addMessageToErrorJson(
704*cc340dd9SEd Tanous                         asyncResp->res.jsonValue,
705*cc340dd9SEd Tanous                         messages::actionParameterUnknown("Reset",
706*cc340dd9SEd Tanous                                                          *reqResetType));
707*cc340dd9SEd Tanous                     res.end();
708*cc340dd9SEd Tanous                     return;
709*cc340dd9SEd Tanous                 }
710*cc340dd9SEd Tanous 
711*cc340dd9SEd Tanous                 crow::connections::systemBus->async_method_call(
712*cc340dd9SEd Tanous                     [asyncResp](const boost::system::error_code ec) {
713*cc340dd9SEd Tanous                         if (ec)
714*cc340dd9SEd Tanous                         {
715*cc340dd9SEd Tanous                             BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
716*cc340dd9SEd Tanous                             asyncResp->res.result(boost::beast::http::status::
717*cc340dd9SEd Tanous                                                       internal_server_error);
718*cc340dd9SEd Tanous                             return;
719*cc340dd9SEd Tanous                         }
720*cc340dd9SEd Tanous                         // TODO Consider support polling mechanism to verify
721*cc340dd9SEd Tanous                         // status of host and chassis after execute the
722*cc340dd9SEd Tanous                         // requested action.
723*cc340dd9SEd Tanous                         BMCWEB_LOG_DEBUG << "Response with no content";
724*cc340dd9SEd Tanous                         asyncResp->res.result(
725*cc340dd9SEd Tanous                             boost::beast::http::status::no_content);
726*cc340dd9SEd Tanous                     },
727*cc340dd9SEd Tanous                     "xyz.openbmc_project.State.Host",
728*cc340dd9SEd Tanous                     "/xyz/openbmc_project/state/host0",
729*cc340dd9SEd Tanous                     "org.freedesktop.DBus.Properties", "Set",
730*cc340dd9SEd Tanous                     "RequestedHostTransition", "xyz.openbmc_project.State.Host",
731*cc340dd9SEd Tanous                     sdbusplus::message::variant<std::string>{command});
732*cc340dd9SEd Tanous             }
733*cc340dd9SEd Tanous             else
734*cc340dd9SEd Tanous             {
735*cc340dd9SEd Tanous                 messages::addMessageToErrorJson(
736*cc340dd9SEd Tanous                     asyncResp->res.jsonValue,
737*cc340dd9SEd Tanous                     messages::actionParameterUnknown("ComputerSystem.Reset",
738*cc340dd9SEd Tanous                                                      item.key()));
739*cc340dd9SEd Tanous             }
740*cc340dd9SEd Tanous         }
741*cc340dd9SEd Tanous     }
742*cc340dd9SEd Tanous };
743*cc340dd9SEd Tanous 
744*cc340dd9SEd Tanous /**
7456617338dSEd Tanous  * Systems derived class for delivering Computer Systems Schema.
746c5b2abe0SLewanczyk, Dawid  */
7471abe55efSEd Tanous class Systems : public Node
7481abe55efSEd Tanous {
749c5b2abe0SLewanczyk, Dawid   public:
750c5b2abe0SLewanczyk, Dawid     /*
751c5b2abe0SLewanczyk, Dawid      * Default Constructor
752c5b2abe0SLewanczyk, Dawid      */
7531abe55efSEd Tanous     Systems(CrowApp &app) :
7541abe55efSEd Tanous         Node(app, "/redfish/v1/Systems/<str>/", std::string())
7551abe55efSEd Tanous     {
756c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
757c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
758c5b2abe0SLewanczyk, Dawid             "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
759c5b2abe0SLewanczyk, Dawid         Node::json["SystemType"] = "Physical";
760c5b2abe0SLewanczyk, Dawid         Node::json["Description"] = "Computer System";
761c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideEnabled"] =
762c5b2abe0SLewanczyk, Dawid             "Disabled"; // TODO(Dawid), get real boot data
763c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideTarget"] =
764c5b2abe0SLewanczyk, Dawid             "None"; // TODO(Dawid), get real boot data
765c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideMode"] =
766c5b2abe0SLewanczyk, Dawid             "Legacy"; // TODO(Dawid), get real boot data
7671abe55efSEd Tanous         Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
7681abe55efSEd Tanous             {"None",      "Pxe",       "Hdd", "Cd",
7691abe55efSEd Tanous              "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
7701abe55efSEd Tanous                                                // data
771c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Count"] = int(0);
772c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
773c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
774c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
775c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
776c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
777c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
778c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
779c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
780c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
781c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
782c5b2abe0SLewanczyk, Dawid     }
783c5b2abe0SLewanczyk, Dawid 
784c5b2abe0SLewanczyk, Dawid   private:
785c5b2abe0SLewanczyk, Dawid     /**
786c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
787c5b2abe0SLewanczyk, Dawid      */
78855c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
7891abe55efSEd Tanous                const std::vector<std::string> &params) override
7901abe55efSEd Tanous     {
791c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
792c5b2abe0SLewanczyk, Dawid         // impossible
7931abe55efSEd Tanous         if (params.size() != 1)
7941abe55efSEd Tanous         {
795c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
796c5b2abe0SLewanczyk, Dawid             res.end();
797c5b2abe0SLewanczyk, Dawid             return;
798c5b2abe0SLewanczyk, Dawid         }
799c5b2abe0SLewanczyk, Dawid 
800c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
801c5b2abe0SLewanczyk, Dawid 
802*cc340dd9SEd Tanous         // TODO Need to support ForceRestart.
803*cc340dd9SEd Tanous         res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
804*cc340dd9SEd Tanous             {"target",
805*cc340dd9SEd Tanous              "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
806*cc340dd9SEd Tanous             {"ResetType@Redfish.AllowableValues",
807*cc340dd9SEd Tanous              {"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
808c5b2abe0SLewanczyk, Dawid 
809a0803efaSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
810c5b2abe0SLewanczyk, Dawid 
8116c34de48SEd Tanous         getLedGroupIdentify(
812a0803efaSEd Tanous             asyncResp,
813a0803efaSEd Tanous             [&](const bool &asserted, const std::shared_ptr<AsyncResp> &aResp) {
8141abe55efSEd Tanous                 if (asserted)
8151abe55efSEd Tanous                 {
816c5b2abe0SLewanczyk, Dawid                     // If led group is asserted, then another call is needed to
817c5b2abe0SLewanczyk, Dawid                     // get led status
8186c34de48SEd Tanous                     getLedIdentify(
819a0803efaSEd Tanous                         aResp, [](const std::string &ledStatus,
820a0803efaSEd Tanous                                   const std::shared_ptr<AsyncResp> &aResp) {
8211abe55efSEd Tanous                             if (!ledStatus.empty())
8221abe55efSEd Tanous                             {
8231abe55efSEd Tanous                                 aResp->res.jsonValue["IndicatorLED"] =
8241abe55efSEd Tanous                                     ledStatus;
825c5b2abe0SLewanczyk, Dawid                             }
826c5b2abe0SLewanczyk, Dawid                         });
8271abe55efSEd Tanous                 }
8281abe55efSEd Tanous                 else
8291abe55efSEd Tanous                 {
83055c7b7a2SEd Tanous                     aResp->res.jsonValue["IndicatorLED"] = "Off";
831c5b2abe0SLewanczyk, Dawid                 }
832c5b2abe0SLewanczyk, Dawid             });
8336c34de48SEd Tanous         getComputerSystem(asyncResp, name);
8346c34de48SEd Tanous         getHostState(asyncResp);
835c5b2abe0SLewanczyk, Dawid     }
836c5b2abe0SLewanczyk, Dawid 
83755c7b7a2SEd Tanous     void doPatch(crow::Response &res, const crow::Request &req,
8381abe55efSEd Tanous                  const std::vector<std::string> &params) override
8391abe55efSEd Tanous     {
840c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
841c5b2abe0SLewanczyk, Dawid         // impossible
8426617338dSEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
8431abe55efSEd Tanous         if (params.size() != 1)
8441abe55efSEd Tanous         {
845c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
846c5b2abe0SLewanczyk, Dawid             return;
847c5b2abe0SLewanczyk, Dawid         }
848c5b2abe0SLewanczyk, Dawid         // Parse JSON request body
849c5b2abe0SLewanczyk, Dawid         nlohmann::json patch;
8501abe55efSEd Tanous         if (!json_util::processJsonFromRequest(res, req, patch))
8511abe55efSEd Tanous         {
852c5b2abe0SLewanczyk, Dawid             return;
853c5b2abe0SLewanczyk, Dawid         }
854c5b2abe0SLewanczyk, Dawid 
8556617338dSEd Tanous         const std::string &name = params[0];
8566617338dSEd Tanous 
85755c7b7a2SEd Tanous         res.jsonValue = Node::json;
85855c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
859c5b2abe0SLewanczyk, Dawid 
8606617338dSEd Tanous         for (const auto &item : patch.items())
8616617338dSEd Tanous         {
8626617338dSEd Tanous             if (item.key() == "IndicatorLed")
8636617338dSEd Tanous             {
8646617338dSEd Tanous                 const std::string *reqLedState =
8656617338dSEd Tanous                     item.value().get_ptr<const std::string *>();
8666617338dSEd Tanous                 if (reqLedState == nullptr)
8676617338dSEd Tanous                 {
8686617338dSEd Tanous                     messages::addMessageToErrorJson(
8696617338dSEd Tanous                         asyncResp->res.jsonValue,
8706617338dSEd Tanous                         messages::propertyValueFormatError(item.value().dump(),
8716617338dSEd Tanous                                                            item.key()));
8726617338dSEd Tanous                     return;
8736617338dSEd Tanous                 }
8746617338dSEd Tanous 
8756617338dSEd Tanous                 // Verify key value
8766617338dSEd Tanous                 std::string dbusLedState;
8776617338dSEd Tanous                 if (*reqLedState == "On")
8786617338dSEd Tanous                 {
8796617338dSEd Tanous                     dbusLedState =
8806617338dSEd Tanous                         "xyz.openbmc_project.Led.Physical.Action.Lit";
8816617338dSEd Tanous                 }
8826617338dSEd Tanous                 else if (*reqLedState == "Blink")
8836617338dSEd Tanous                 {
8846617338dSEd Tanous                     dbusLedState =
8856617338dSEd Tanous                         "xyz.openbmc_project.Led.Physical.Action.Blinking";
8866617338dSEd Tanous                 }
8876617338dSEd Tanous                 else if (*reqLedState == "Off")
8886617338dSEd Tanous                 {
8896617338dSEd Tanous                     dbusLedState =
8906617338dSEd Tanous                         "xyz.openbmc_project.Led.Physical.Action.Off";
8916617338dSEd Tanous                 }
8926617338dSEd Tanous                 else
8936617338dSEd Tanous                 {
8946617338dSEd Tanous                     messages::addMessageToJsonRoot(
8956617338dSEd Tanous                         res.jsonValue, messages::propertyValueNotInList(
8966617338dSEd Tanous                                            *reqLedState, "IndicatorLED"));
8976617338dSEd Tanous                     return;
8986617338dSEd Tanous                 }
8996617338dSEd Tanous 
9006c34de48SEd Tanous                 getHostState(asyncResp);
9016c34de48SEd Tanous                 getComputerSystem(asyncResp, name);
902c5b2abe0SLewanczyk, Dawid 
903c5b2abe0SLewanczyk, Dawid                 // Update led group
90455c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Update led group.";
90555c7b7a2SEd Tanous                 crow::connections::systemBus->async_method_call(
9066617338dSEd Tanous                     [asyncResp{std::move(asyncResp)}](
907c5b2abe0SLewanczyk, Dawid                         const boost::system::error_code ec) {
9081abe55efSEd Tanous                         if (ec)
9091abe55efSEd Tanous                         {
91055c7b7a2SEd Tanous                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9116617338dSEd Tanous                             asyncResp->res.result(boost::beast::http::status::
9126617338dSEd Tanous                                                       internal_server_error);
913c5b2abe0SLewanczyk, Dawid                             return;
914c5b2abe0SLewanczyk, Dawid                         }
91555c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Led group update done.";
916c5b2abe0SLewanczyk, Dawid                     },
917c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.LED.GroupManager",
918c5b2abe0SLewanczyk, Dawid                     "/xyz/openbmc_project/led/groups/enclosure_identify",
919c5b2abe0SLewanczyk, Dawid                     "org.freedesktop.DBus.Properties", "Set",
920c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.Led.Group", "Asserted",
921c5b2abe0SLewanczyk, Dawid                     sdbusplus::message::variant<bool>(
9226617338dSEd Tanous                         (dbusLedState ==
9236617338dSEd Tanous                                  "xyz.openbmc_project.Led.Physical.Action.Off"
9246617338dSEd Tanous                              ? false
9256617338dSEd Tanous                              : true)));
926c5b2abe0SLewanczyk, Dawid                 // Update identify led status
92755c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
92855c7b7a2SEd Tanous                 crow::connections::systemBus->async_method_call(
9296617338dSEd Tanous                     [asyncResp{std::move(asyncResp)},
9306617338dSEd Tanous                      reqLedState{std::move(*reqLedState)}](
931c5b2abe0SLewanczyk, Dawid                         const boost::system::error_code ec) {
9321abe55efSEd Tanous                         if (ec)
9331abe55efSEd Tanous                         {
93455c7b7a2SEd Tanous                             BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
9356617338dSEd Tanous                             asyncResp->res.result(boost::beast::http::status::
9366617338dSEd Tanous                                                       internal_server_error);
937c5b2abe0SLewanczyk, Dawid                             return;
938c5b2abe0SLewanczyk, Dawid                         }
93955c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Led state update done.";
9406617338dSEd Tanous                         asyncResp->res.jsonValue["IndicatorLED"] =
9416617338dSEd Tanous                             std::move(reqLedState);
942c5b2abe0SLewanczyk, Dawid                     },
943c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.LED.Controller.identify",
944c5b2abe0SLewanczyk, Dawid                     "/xyz/openbmc_project/led/physical/identify",
945c5b2abe0SLewanczyk, Dawid                     "org.freedesktop.DBus.Properties", "Set",
946c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.Led.Physical", "State",
9476617338dSEd Tanous                     sdbusplus::message::variant<std::string>(dbusLedState));
9486617338dSEd Tanous             }
9496617338dSEd Tanous             else
9506617338dSEd Tanous             {
9516617338dSEd Tanous                 messages::addMessageToErrorJson(
9526617338dSEd Tanous                     asyncResp->res.jsonValue,
9536617338dSEd Tanous                     messages::propertyNotWritable(item.key()));
9546617338dSEd Tanous                 return;
9556617338dSEd Tanous             }
956c5b2abe0SLewanczyk, Dawid         }
957c5b2abe0SLewanczyk, Dawid     }
958c5b2abe0SLewanczyk, Dawid };
959c5b2abe0SLewanczyk, Dawid } // namespace redfish
960