xref: /openbmc/bmcweb/features/redfish/lib/systems.hpp (revision 1abe55ef9844afcddcab9d862ae06118f3a2390c)
1c5b2abe0SLewanczyk, Dawid /*
2c5b2abe0SLewanczyk, Dawid // Copyright (c) 2018 Intel Corporation
3c5b2abe0SLewanczyk, Dawid //
4c5b2abe0SLewanczyk, Dawid // Licensed under the Apache License, Version 2.0 (the "License");
5c5b2abe0SLewanczyk, Dawid // you may not use this file except in compliance with the License.
6c5b2abe0SLewanczyk, Dawid // You may obtain a copy of the License at
7c5b2abe0SLewanczyk, Dawid //
8c5b2abe0SLewanczyk, Dawid //      http://www.apache.org/licenses/LICENSE-2.0
9c5b2abe0SLewanczyk, Dawid //
10c5b2abe0SLewanczyk, Dawid // Unless required by applicable law or agreed to in writing, software
11c5b2abe0SLewanczyk, Dawid // distributed under the License is distributed on an "AS IS" BASIS,
12c5b2abe0SLewanczyk, Dawid // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13c5b2abe0SLewanczyk, Dawid // See the License for the specific language governing permissions and
14c5b2abe0SLewanczyk, Dawid // limitations under the License.
15c5b2abe0SLewanczyk, Dawid */
16c5b2abe0SLewanczyk, Dawid #pragma once
17c5b2abe0SLewanczyk, Dawid 
18*1abe55efSEd Tanous #include "boost/container/flat_map.hpp"
19*1abe55efSEd Tanous #include "node.hpp"
20*1abe55efSEd Tanous 
21c5b2abe0SLewanczyk, Dawid #include <error_messages.hpp>
22c5b2abe0SLewanczyk, Dawid #include <utils/json_utils.hpp>
23c5b2abe0SLewanczyk, Dawid 
24*1abe55efSEd Tanous namespace redfish
25*1abe55efSEd Tanous {
26c5b2abe0SLewanczyk, Dawid 
27c5b2abe0SLewanczyk, Dawid /**
28c5b2abe0SLewanczyk, Dawid  * SystemAsyncResp
29c5b2abe0SLewanczyk, Dawid  * Gathers data needed for response processing after async calls are done
30c5b2abe0SLewanczyk, Dawid  */
31*1abe55efSEd Tanous class SystemAsyncResp
32*1abe55efSEd Tanous {
33c5b2abe0SLewanczyk, Dawid   public:
34*1abe55efSEd Tanous     SystemAsyncResp(crow::Response &response) : res(response)
35*1abe55efSEd Tanous     {
36*1abe55efSEd Tanous     }
37c5b2abe0SLewanczyk, Dawid 
38*1abe55efSEd Tanous     ~SystemAsyncResp()
39*1abe55efSEd Tanous     {
40*1abe55efSEd Tanous         if (res.result() != (boost::beast::http::status::ok))
41*1abe55efSEd Tanous         {
42*1abe55efSEd Tanous             // Reset the json object to clear out any data that made it in
43*1abe55efSEd Tanous             // before the error happened todo(ed) handle error condition with
44*1abe55efSEd Tanous             // proper code
4555c7b7a2SEd Tanous             res.jsonValue = messages::internalError();
46c5b2abe0SLewanczyk, Dawid         }
47c5b2abe0SLewanczyk, Dawid         res.end();
48c5b2abe0SLewanczyk, Dawid     }
49c5b2abe0SLewanczyk, Dawid 
50*1abe55efSEd Tanous     void setErrorStatus()
51*1abe55efSEd Tanous     {
52c5b2abe0SLewanczyk, Dawid         res.result(boost::beast::http::status::internal_server_error);
53c5b2abe0SLewanczyk, Dawid     }
54c5b2abe0SLewanczyk, Dawid 
5555c7b7a2SEd Tanous     crow::Response &res;
56c5b2abe0SLewanczyk, Dawid };
57c5b2abe0SLewanczyk, Dawid 
58c5b2abe0SLewanczyk, Dawid /**
59c5b2abe0SLewanczyk, Dawid  * OnDemandSystemsProvider
60c5b2abe0SLewanczyk, Dawid  * Board provider class that retrieves data directly from dbus, before seting
61c5b2abe0SLewanczyk, Dawid  * it into JSON output. This does not cache any data.
62c5b2abe0SLewanczyk, Dawid  *
63c5b2abe0SLewanczyk, Dawid  * Class can be a good example on how to scale different data providing
64c5b2abe0SLewanczyk, Dawid  * solutions to produce single schema output.
65c5b2abe0SLewanczyk, Dawid  *
66c5b2abe0SLewanczyk, Dawid  * TODO(Pawel)
67c5b2abe0SLewanczyk, Dawid  * This perhaps shall be different file, which has to be chosen on compile time
68c5b2abe0SLewanczyk, Dawid  * depending on OEM needs
69c5b2abe0SLewanczyk, Dawid  */
70*1abe55efSEd Tanous class OnDemandSystemsProvider
71*1abe55efSEd Tanous {
72c5b2abe0SLewanczyk, Dawid   public:
73c5b2abe0SLewanczyk, Dawid     template <typename CallbackFunc>
74*1abe55efSEd Tanous     void getBaseboardList(CallbackFunc &&callback)
75*1abe55efSEd Tanous     {
7655c7b7a2SEd Tanous         BMCWEB_LOG_DEBUG << "Get list of available boards.";
7755c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
78*1abe55efSEd Tanous             [callback{std::move(callback)}](
79*1abe55efSEd Tanous                 const boost::system::error_code ec,
80c5b2abe0SLewanczyk, Dawid                 const std::vector<std::string> &resp) {
81*1abe55efSEd Tanous                 // Callback requires vector<string> to retrieve all available
82*1abe55efSEd Tanous                 // board list.
83d76323e5SEd Tanous                 std::vector<std::string> boardList;
84*1abe55efSEd Tanous                 if (ec)
85*1abe55efSEd Tanous                 {
86*1abe55efSEd Tanous                     // Something wrong on DBus, the error_code is not important
87*1abe55efSEd Tanous                     // at this moment, just return success=false, and empty
88*1abe55efSEd Tanous                     // output. Since size of vector may vary depending on
89*1abe55efSEd Tanous                     // information from Entity Manager, and empty output could
90*1abe55efSEd Tanous                     // not be treated same way as error.
91d76323e5SEd Tanous                     callback(false, boardList);
92c5b2abe0SLewanczyk, Dawid                     return;
93c5b2abe0SLewanczyk, Dawid                 }
9455c7b7a2SEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
95c5b2abe0SLewanczyk, Dawid                 // Iterate over all retrieved ObjectPaths.
96*1abe55efSEd Tanous                 for (const std::string &objpath : resp)
97*1abe55efSEd Tanous                 {
98d76323e5SEd Tanous                     std::size_t lastPos = objpath.rfind("/");
99*1abe55efSEd Tanous                     if (lastPos != std::string::npos)
100*1abe55efSEd Tanous                     {
101d76323e5SEd Tanous                         boardList.emplace_back(objpath.substr(lastPos + 1));
102c5b2abe0SLewanczyk, Dawid                     }
103c5b2abe0SLewanczyk, Dawid                 }
104c5b2abe0SLewanczyk, Dawid                 // Finally make a callback with useful data
105d76323e5SEd Tanous                 callback(true, boardList);
106c5b2abe0SLewanczyk, Dawid             },
107c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.ObjectMapper",
108c5b2abe0SLewanczyk, Dawid             "/xyz/openbmc_project/object_mapper",
109c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
110c5b2abe0SLewanczyk, Dawid             "/xyz/openbmc_project/inventory", int32_t(0),
111c5b2abe0SLewanczyk, Dawid             std::array<const char *, 1>{
112c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Inventory.Item.Board"});
113c5b2abe0SLewanczyk, Dawid     };
114c5b2abe0SLewanczyk, Dawid 
115c5b2abe0SLewanczyk, Dawid     /**
116c5b2abe0SLewanczyk, Dawid      * @brief Retrieves computer system properties over dbus
117c5b2abe0SLewanczyk, Dawid      *
118c5b2abe0SLewanczyk, Dawid      * @param[in] aResp Shared pointer for completing asynchronous calls
119c5b2abe0SLewanczyk, Dawid      * @param[in] name  Computer system name from request
120c5b2abe0SLewanczyk, Dawid      *
121c5b2abe0SLewanczyk, Dawid      * @return None.
122c5b2abe0SLewanczyk, Dawid      */
123c5b2abe0SLewanczyk, Dawid     void getComputerSystem(std::shared_ptr<SystemAsyncResp> aResp,
124*1abe55efSEd Tanous                            const std::string &name)
125*1abe55efSEd Tanous     {
126c5b2abe0SLewanczyk, Dawid         const std::array<const char *, 5> interfaces = {
127c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Inventory.Decorator.Asset",
128c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Inventory.Item.Cpu",
129c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Inventory.Item.Dimm",
130c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Inventory.Item.System",
131c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Common.UUID",
132c5b2abe0SLewanczyk, Dawid         };
13355c7b7a2SEd Tanous         BMCWEB_LOG_DEBUG << "Get available system components.";
13455c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
135c5b2abe0SLewanczyk, Dawid             [name, aResp{std::move(aResp)}](
136c5b2abe0SLewanczyk, Dawid                 const boost::system::error_code ec,
137c5b2abe0SLewanczyk, Dawid                 const std::vector<std::pair<
138*1abe55efSEd Tanous                     std::string, std::vector<std::pair<
139*1abe55efSEd Tanous                                      std::string, std::vector<std::string>>>>>
140c5b2abe0SLewanczyk, Dawid                     &subtree) {
141*1abe55efSEd Tanous                 if (ec)
142*1abe55efSEd Tanous                 {
14355c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error";
144c5b2abe0SLewanczyk, Dawid                     aResp->setErrorStatus();
145c5b2abe0SLewanczyk, Dawid                     return;
146c5b2abe0SLewanczyk, Dawid                 }
147c5b2abe0SLewanczyk, Dawid                 bool foundName = false;
148c5b2abe0SLewanczyk, Dawid                 // Iterate over all retrieved ObjectPaths.
149*1abe55efSEd Tanous                 for (const std::pair<
150*1abe55efSEd Tanous                          std::string,
151*1abe55efSEd Tanous                          std::vector<
152*1abe55efSEd Tanous                              std::pair<std::string, std::vector<std::string>>>>
153*1abe55efSEd Tanous                          &object : subtree)
154*1abe55efSEd Tanous                 {
155c5b2abe0SLewanczyk, Dawid                     const std::string &path = object.first;
15655c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Got path: " << path;
157*1abe55efSEd Tanous                     const std::vector<
158*1abe55efSEd Tanous                         std::pair<std::string, std::vector<std::string>>>
159c5b2abe0SLewanczyk, Dawid                         &connectionNames = object.second;
160*1abe55efSEd Tanous                     if (connectionNames.size() < 1)
161*1abe55efSEd Tanous                     {
162c5b2abe0SLewanczyk, Dawid                         continue;
163c5b2abe0SLewanczyk, Dawid                     }
164c5b2abe0SLewanczyk, Dawid                     // Check if computer system exist
165*1abe55efSEd Tanous                     if (boost::ends_with(path, name))
166*1abe55efSEd Tanous                     {
167c5b2abe0SLewanczyk, Dawid                         foundName = true;
16855c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Found name: " << name;
169*1abe55efSEd Tanous                         const std::string connectionName =
170*1abe55efSEd Tanous                             connectionNames[0].first;
17155c7b7a2SEd Tanous                         crow::connections::systemBus->async_method_call(
172c5b2abe0SLewanczyk, Dawid                             [aResp, name(std::string(name))](
173c5b2abe0SLewanczyk, Dawid                                 const boost::system::error_code ec,
174*1abe55efSEd Tanous                                 const std::vector<
175*1abe55efSEd Tanous                                     std::pair<std::string, VariantType>>
176c5b2abe0SLewanczyk, Dawid                                     &propertiesList) {
177*1abe55efSEd Tanous                                 if (ec)
178*1abe55efSEd Tanous                                 {
179*1abe55efSEd Tanous                                     BMCWEB_LOG_ERROR << "DBUS response error: "
180*1abe55efSEd Tanous                                                      << ec;
181c5b2abe0SLewanczyk, Dawid                                     aResp->setErrorStatus();
182c5b2abe0SLewanczyk, Dawid                                     return;
183c5b2abe0SLewanczyk, Dawid                                 }
184*1abe55efSEd Tanous                                 BMCWEB_LOG_DEBUG << "Got "
185*1abe55efSEd Tanous                                                  << propertiesList.size()
186c5b2abe0SLewanczyk, Dawid                                                  << "properties for system";
187*1abe55efSEd Tanous                                 for (const std::pair<std::string, VariantType>
188*1abe55efSEd Tanous                                          &property : propertiesList)
189*1abe55efSEd Tanous                                 {
190c5b2abe0SLewanczyk, Dawid                                     const std::string *value =
191*1abe55efSEd Tanous                                         mapbox::getPtr<const std::string>(
192*1abe55efSEd Tanous                                             property.second);
193*1abe55efSEd Tanous                                     if (value != nullptr)
194*1abe55efSEd Tanous                                     {
195*1abe55efSEd Tanous                                         aResp->res.jsonValue[property.first] =
196*1abe55efSEd Tanous                                             *value;
197c5b2abe0SLewanczyk, Dawid                                     }
198c5b2abe0SLewanczyk, Dawid                                 }
19955c7b7a2SEd Tanous                                 aResp->res.jsonValue["Name"] = name;
20055c7b7a2SEd Tanous                                 aResp->res.jsonValue["Id"] =
20155c7b7a2SEd Tanous                                     aResp->res.jsonValue["SerialNumber"];
202c5b2abe0SLewanczyk, Dawid                             },
203*1abe55efSEd Tanous                             connectionName, path,
204*1abe55efSEd Tanous                             "org.freedesktop.DBus.Properties", "GetAll",
205*1abe55efSEd Tanous                             "xyz.openbmc_project.Inventory.Decorator.Asset");
206*1abe55efSEd Tanous                     }
207*1abe55efSEd Tanous                     else
208*1abe55efSEd Tanous                     {
209*1abe55efSEd Tanous                         // This is not system, so check if it's cpu, dimm, UUID
210*1abe55efSEd Tanous                         // or BiosVer
211*1abe55efSEd Tanous                         for (auto const &s : connectionNames)
212*1abe55efSEd Tanous                         {
213*1abe55efSEd Tanous                             for (auto const &i : s.second)
214*1abe55efSEd Tanous                             {
215*1abe55efSEd Tanous                                 if (boost::ends_with(i, "Dimm"))
216*1abe55efSEd Tanous                                 {
217*1abe55efSEd Tanous                                     BMCWEB_LOG_DEBUG
218*1abe55efSEd Tanous                                         << "Found Dimm, now get it properties.";
21955c7b7a2SEd Tanous                                     crow::connections::systemBus->async_method_call(
220*1abe55efSEd Tanous                                         [&, aResp](
221*1abe55efSEd Tanous                                             const boost::system::error_code ec,
222c5b2abe0SLewanczyk, Dawid                                             const std::vector<std::pair<
223*1abe55efSEd Tanous                                                 std::string, VariantType>>
224*1abe55efSEd Tanous                                                 &properties) {
225*1abe55efSEd Tanous                                             if (ec)
226*1abe55efSEd Tanous                                             {
227*1abe55efSEd Tanous                                                 BMCWEB_LOG_ERROR
228*1abe55efSEd Tanous                                                     << "DBUS response error "
229*1abe55efSEd Tanous                                                     << ec;
230c5b2abe0SLewanczyk, Dawid                                                 aResp->setErrorStatus();
231c5b2abe0SLewanczyk, Dawid                                                 return;
232c5b2abe0SLewanczyk, Dawid                                             }
233*1abe55efSEd Tanous                                             BMCWEB_LOG_DEBUG
234*1abe55efSEd Tanous                                                 << "Got " << properties.size()
235c5b2abe0SLewanczyk, Dawid                                                 << "Dimm properties.";
236*1abe55efSEd Tanous                                             for (const auto &p : properties)
237*1abe55efSEd Tanous                                             {
238*1abe55efSEd Tanous                                                 if (p.first == "MemorySize")
239*1abe55efSEd Tanous                                                 {
240c5b2abe0SLewanczyk, Dawid                                                     const std::string *value =
241*1abe55efSEd Tanous                                                         mapbox::getPtr<
242*1abe55efSEd Tanous                                                             const std::string>(
243*1abe55efSEd Tanous                                                             p.second);
244*1abe55efSEd Tanous                                                     if ((value != nullptr) &&
245*1abe55efSEd Tanous                                                         (*value != "NULL"))
246*1abe55efSEd Tanous                                                     {
247c5b2abe0SLewanczyk, Dawid                                                         // Remove units char
248c5b2abe0SLewanczyk, Dawid                                                         int32_t unitCoeff;
249*1abe55efSEd Tanous                                                         if (boost::ends_with(
250*1abe55efSEd Tanous                                                                 *value, "MB"))
251*1abe55efSEd Tanous                                                         {
252c5b2abe0SLewanczyk, Dawid                                                             unitCoeff = 1000;
253*1abe55efSEd Tanous                                                         }
254*1abe55efSEd Tanous                                                         else if (boost::
255*1abe55efSEd Tanous                                                                      ends_with(
256*1abe55efSEd Tanous                                                                          *value,
257*1abe55efSEd Tanous                                                                          "KB"))
258*1abe55efSEd Tanous                                                         {
259c5b2abe0SLewanczyk, Dawid                                                             unitCoeff = 1000000;
260*1abe55efSEd Tanous                                                         }
261*1abe55efSEd Tanous                                                         else
262*1abe55efSEd Tanous                                                         {
263a434f2bdSEd Tanous                                                             BMCWEB_LOG_ERROR
264*1abe55efSEd Tanous                                                                 << "Unsupported"
265*1abe55efSEd Tanous                                                                    " memory "
266*1abe55efSEd Tanous                                                                    "units";
267*1abe55efSEd Tanous                                                             aResp
268*1abe55efSEd Tanous                                                                 ->setErrorStatus();
269c5b2abe0SLewanczyk, Dawid                                                             return;
270c5b2abe0SLewanczyk, Dawid                                                         }
271c5b2abe0SLewanczyk, Dawid 
272*1abe55efSEd Tanous                                                         auto memSize =
273*1abe55efSEd Tanous                                                             boost::lexical_cast<
274*1abe55efSEd Tanous                                                                 int>(value->substr(
275*1abe55efSEd Tanous                                                                 0,
276*1abe55efSEd Tanous                                                                 value->length() -
277*1abe55efSEd Tanous                                                                     2));
278*1abe55efSEd Tanous                                                         aResp->res.jsonValue
279*1abe55efSEd Tanous                                                             ["TotalSystemMemory"
280*1abe55efSEd Tanous                                                              "GiB"] +=
281c5b2abe0SLewanczyk, Dawid                                                             memSize * unitCoeff;
282*1abe55efSEd Tanous                                                         aResp->res.jsonValue
283*1abe55efSEd Tanous                                                             ["MemorySummary"]
284*1abe55efSEd Tanous                                                             ["Status"]
285*1abe55efSEd Tanous                                                             ["State"] =
286*1abe55efSEd Tanous                                                             "Enabled";
287c5b2abe0SLewanczyk, Dawid                                                     }
288c5b2abe0SLewanczyk, Dawid                                                 }
289c5b2abe0SLewanczyk, Dawid                                             }
290c5b2abe0SLewanczyk, Dawid                                         },
291*1abe55efSEd Tanous                                         s.first, path,
292*1abe55efSEd Tanous                                         "org.freedesktop.DBus.Properties",
293*1abe55efSEd Tanous                                         "GetAll",
294*1abe55efSEd Tanous                                         "xyz.openbmc_project.Inventory.Item."
295*1abe55efSEd Tanous                                         "Dimm");
296*1abe55efSEd Tanous                                 }
297*1abe55efSEd Tanous                                 else if (boost::ends_with(i, "Cpu"))
298*1abe55efSEd Tanous                                 {
299*1abe55efSEd Tanous                                     BMCWEB_LOG_DEBUG
300*1abe55efSEd Tanous                                         << "Found Cpu, now get it properties.";
301*1abe55efSEd Tanous                                     crow::connections::systemBus
302*1abe55efSEd Tanous                                         ->async_method_call(
303*1abe55efSEd Tanous                                             [&, aResp](
304*1abe55efSEd Tanous                                                 const boost::system::error_code
305*1abe55efSEd Tanous                                                     ec,
306c5b2abe0SLewanczyk, Dawid                                                 const std::vector<std::pair<
307*1abe55efSEd Tanous                                                     std::string, VariantType>>
308*1abe55efSEd Tanous                                                     &properties) {
309*1abe55efSEd Tanous                                                 if (ec)
310*1abe55efSEd Tanous                                                 {
311*1abe55efSEd Tanous                                                     BMCWEB_LOG_ERROR
312*1abe55efSEd Tanous                                                         << "DBUS response "
313*1abe55efSEd Tanous                                                            "error "
314*1abe55efSEd Tanous                                                         << ec;
315c5b2abe0SLewanczyk, Dawid                                                     aResp->setErrorStatus();
316c5b2abe0SLewanczyk, Dawid                                                     return;
317c5b2abe0SLewanczyk, Dawid                                                 }
318*1abe55efSEd Tanous                                                 BMCWEB_LOG_DEBUG
319*1abe55efSEd Tanous                                                     << "Got "
320*1abe55efSEd Tanous                                                     << properties.size()
321c5b2abe0SLewanczyk, Dawid                                                     << "Cpu properties.";
322*1abe55efSEd Tanous                                                 for (const auto &p : properties)
323*1abe55efSEd Tanous                                                 {
324*1abe55efSEd Tanous                                                     if (p.first ==
325*1abe55efSEd Tanous                                                         "ProcessorFamily")
326*1abe55efSEd Tanous                                                     {
327*1abe55efSEd Tanous                                                         const std::string
328*1abe55efSEd Tanous                                                             *value =
329*1abe55efSEd Tanous                                                                 mapbox::getPtr<
330*1abe55efSEd Tanous                                                                     const std::
331*1abe55efSEd Tanous                                                                         string>(
332*1abe55efSEd Tanous                                                                     p.second);
333*1abe55efSEd Tanous                                                         if (value != nullptr)
334*1abe55efSEd Tanous                                                         {
335*1abe55efSEd Tanous                                                             aResp->res.jsonValue
336*1abe55efSEd Tanous                                                                 ["ProcessorSumm"
337*1abe55efSEd Tanous                                                                  "ary"]
338*1abe55efSEd Tanous                                                                 ["Count"] =
339c5b2abe0SLewanczyk, Dawid                                                                 aResp->res
340*1abe55efSEd Tanous                                                                     .jsonValue
341*1abe55efSEd Tanous                                                                         ["Proce"
342*1abe55efSEd Tanous                                                                          "ssorS"
343*1abe55efSEd Tanous                                                                          "ummar"
344*1abe55efSEd Tanous                                                                          "y"]
345*1abe55efSEd Tanous                                                                         ["Coun"
346*1abe55efSEd Tanous                                                                          "t"]
347*1abe55efSEd Tanous                                                                     .get<
348*1abe55efSEd Tanous                                                                         int>() +
349c5b2abe0SLewanczyk, Dawid                                                                 1;
350*1abe55efSEd Tanous                                                             aResp->res.jsonValue
351*1abe55efSEd Tanous                                                                 ["ProcessorSumm"
352*1abe55efSEd Tanous                                                                  "ary"]
353*1abe55efSEd Tanous                                                                 ["Status"]
354*1abe55efSEd Tanous                                                                 ["State"] =
355c5b2abe0SLewanczyk, Dawid                                                                 "Enabled";
356*1abe55efSEd Tanous                                                             aResp->res.jsonValue
357*1abe55efSEd Tanous                                                                 ["ProcessorSumm"
358*1abe55efSEd Tanous                                                                  "ary"]
359*1abe55efSEd Tanous                                                                 ["Model"] =
360c5b2abe0SLewanczyk, Dawid                                                                 *value;
361c5b2abe0SLewanczyk, Dawid                                                         }
362c5b2abe0SLewanczyk, Dawid                                                     }
363c5b2abe0SLewanczyk, Dawid                                                 }
364c5b2abe0SLewanczyk, Dawid                                             },
365*1abe55efSEd Tanous                                             s.first, path,
366*1abe55efSEd Tanous                                             "org.freedesktop.DBus.Properties",
367*1abe55efSEd Tanous                                             "GetAll",
368*1abe55efSEd Tanous                                             "xyz.openbmc_project.Inventory."
369*1abe55efSEd Tanous                                             "Item.Cpu");
370*1abe55efSEd Tanous                                 }
371*1abe55efSEd Tanous                                 else if (boost::ends_with(i, "UUID"))
372*1abe55efSEd Tanous                                 {
373*1abe55efSEd Tanous                                     BMCWEB_LOG_DEBUG
374*1abe55efSEd Tanous                                         << "Found UUID, now get it properties.";
37555c7b7a2SEd Tanous                                     crow::connections::systemBus->async_method_call(
376*1abe55efSEd Tanous                                         [aResp](
377*1abe55efSEd Tanous                                             const boost::system::error_code ec,
378c5b2abe0SLewanczyk, Dawid                                             const std::vector<std::pair<
379*1abe55efSEd Tanous                                                 std::string, VariantType>>
380*1abe55efSEd Tanous                                                 &properties) {
381*1abe55efSEd Tanous                                             if (ec)
382*1abe55efSEd Tanous                                             {
383*1abe55efSEd Tanous                                                 BMCWEB_LOG_DEBUG
384*1abe55efSEd Tanous                                                     << "DBUS response error "
385*1abe55efSEd Tanous                                                     << ec;
386c5b2abe0SLewanczyk, Dawid                                                 aResp->setErrorStatus();
387c5b2abe0SLewanczyk, Dawid                                                 return;
388c5b2abe0SLewanczyk, Dawid                                             }
389*1abe55efSEd Tanous                                             BMCWEB_LOG_DEBUG
390*1abe55efSEd Tanous                                                 << "Got " << properties.size()
391c5b2abe0SLewanczyk, Dawid                                                 << "UUID properties.";
392*1abe55efSEd Tanous                                             for (const std::pair<std::string,
393*1abe55efSEd Tanous                                                                  VariantType>
394*1abe55efSEd Tanous                                                      &p : properties)
395*1abe55efSEd Tanous                                             {
396*1abe55efSEd Tanous                                                 if (p.first == "BIOSVer")
397*1abe55efSEd Tanous                                                 {
398c5b2abe0SLewanczyk, Dawid                                                     const std::string *value =
399*1abe55efSEd Tanous                                                         mapbox::getPtr<
400*1abe55efSEd Tanous                                                             const std::string>(
401*1abe55efSEd Tanous                                                             p.second);
402*1abe55efSEd Tanous                                                     if (value != nullptr)
403*1abe55efSEd Tanous                                                     {
404*1abe55efSEd Tanous                                                         aResp->res.jsonValue
405*1abe55efSEd Tanous                                                             ["BiosVersion"] =
406*1abe55efSEd Tanous                                                             *value;
407c5b2abe0SLewanczyk, Dawid                                                     }
408c5b2abe0SLewanczyk, Dawid                                                 }
409*1abe55efSEd Tanous                                                 if (p.first == "UUID")
410*1abe55efSEd Tanous                                                 {
411c5b2abe0SLewanczyk, Dawid                                                     const std::string *value =
412*1abe55efSEd Tanous                                                         mapbox::getPtr<
413*1abe55efSEd Tanous                                                             const std::string>(
414*1abe55efSEd Tanous                                                             p.second);
415*1abe55efSEd Tanous                                                     BMCWEB_LOG_DEBUG
416*1abe55efSEd Tanous                                                         << "UUID = " << *value
417*1abe55efSEd Tanous                                                         << " length "
418*1abe55efSEd Tanous                                                         << value->length();
419*1abe55efSEd Tanous                                                     if (value != nullptr)
420*1abe55efSEd Tanous                                                     {
421*1abe55efSEd Tanous                                                         // Workaround for to
422*1abe55efSEd Tanous                                                         // short return str in
423*1abe55efSEd Tanous                                                         // smbios demo app, 32
424*1abe55efSEd Tanous                                                         // bytes are described
425*1abe55efSEd Tanous                                                         // by spec
426*1abe55efSEd Tanous                                                         if (value->length() >
427*1abe55efSEd Tanous                                                                 0 &&
428*1abe55efSEd Tanous                                                             value->length() <
429*1abe55efSEd Tanous                                                                 32)
430*1abe55efSEd Tanous                                                         {
431*1abe55efSEd Tanous                                                             std::string
432*1abe55efSEd Tanous                                                                 correctedValue =
433*1abe55efSEd Tanous                                                                     *value;
434*1abe55efSEd Tanous                                                             correctedValue.append(
435*1abe55efSEd Tanous                                                                 32 -
436*1abe55efSEd Tanous                                                                     value
437*1abe55efSEd Tanous                                                                         ->length(),
438c5b2abe0SLewanczyk, Dawid                                                                 '0');
439*1abe55efSEd Tanous                                                             value =
440*1abe55efSEd Tanous                                                                 &correctedValue;
441*1abe55efSEd Tanous                                                         }
442*1abe55efSEd Tanous                                                         else if (
443*1abe55efSEd Tanous                                                             value->length() ==
444*1abe55efSEd Tanous                                                             32)
445*1abe55efSEd Tanous                                                         {
446*1abe55efSEd Tanous                                                             aResp->res.jsonValue
447*1abe55efSEd Tanous                                                                 ["UUID"] =
448*1abe55efSEd Tanous                                                                 value->substr(
449*1abe55efSEd Tanous                                                                     0, 8) +
450*1abe55efSEd Tanous                                                                 "-" +
451*1abe55efSEd Tanous                                                                 value->substr(
452*1abe55efSEd Tanous                                                                     8, 4) +
453*1abe55efSEd Tanous                                                                 "-" +
454*1abe55efSEd Tanous                                                                 value->substr(
455*1abe55efSEd Tanous                                                                     12, 4) +
456*1abe55efSEd Tanous                                                                 "-" +
457*1abe55efSEd Tanous                                                                 value->substr(
458*1abe55efSEd Tanous                                                                     16, 4) +
459*1abe55efSEd Tanous                                                                 "-" +
460*1abe55efSEd Tanous                                                                 value->substr(
461*1abe55efSEd Tanous                                                                     20, 12);
462c5b2abe0SLewanczyk, Dawid                                                         }
463c5b2abe0SLewanczyk, Dawid                                                     }
464c5b2abe0SLewanczyk, Dawid                                                 }
465c5b2abe0SLewanczyk, Dawid                                             }
466c5b2abe0SLewanczyk, Dawid                                         },
467*1abe55efSEd Tanous                                         s.first, path,
468*1abe55efSEd Tanous                                         "org.freedesktop.DBus.Properties",
469*1abe55efSEd Tanous                                         "GetAll",
470*1abe55efSEd Tanous                                         "xyz.openbmc_project.Common.UUID");
471c5b2abe0SLewanczyk, Dawid                                 }
472c5b2abe0SLewanczyk, Dawid                             }
473c5b2abe0SLewanczyk, Dawid                         }
474c5b2abe0SLewanczyk, Dawid                     }
475c5b2abe0SLewanczyk, Dawid                 }
476*1abe55efSEd Tanous                 if (foundName == false)
477*1abe55efSEd Tanous                 {
478c5b2abe0SLewanczyk, Dawid                     aResp->setErrorStatus();
479c5b2abe0SLewanczyk, Dawid                 }
480c5b2abe0SLewanczyk, Dawid             },
481c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.ObjectMapper",
482c5b2abe0SLewanczyk, Dawid             "/xyz/openbmc_project/object_mapper",
483c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.ObjectMapper", "GetSubTree",
484c5b2abe0SLewanczyk, Dawid             "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
485c5b2abe0SLewanczyk, Dawid     }
486c5b2abe0SLewanczyk, Dawid 
487c5b2abe0SLewanczyk, Dawid     /**
488c5b2abe0SLewanczyk, Dawid      * @brief Retrieves identify led group properties over dbus
489c5b2abe0SLewanczyk, Dawid      *
490c5b2abe0SLewanczyk, Dawid      * @param[in] aResp     Shared pointer for completing asynchronous calls.
491c5b2abe0SLewanczyk, Dawid      * @param[in] callback  Callback for process retrieved data.
492c5b2abe0SLewanczyk, Dawid      *
493c5b2abe0SLewanczyk, Dawid      * @return None.
494c5b2abe0SLewanczyk, Dawid      */
495c5b2abe0SLewanczyk, Dawid     template <typename CallbackFunc>
496c5b2abe0SLewanczyk, Dawid     void getLedGroupIdentify(std::shared_ptr<SystemAsyncResp> aResp,
497*1abe55efSEd Tanous                              CallbackFunc &&callback)
498*1abe55efSEd Tanous     {
49955c7b7a2SEd Tanous         BMCWEB_LOG_DEBUG << "Get led groups";
50055c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
501*1abe55efSEd Tanous             [aResp{std::move(aResp)},
502*1abe55efSEd Tanous              &callback](const boost::system::error_code &ec,
503*1abe55efSEd Tanous                         const ManagedObjectsType &resp) {
504*1abe55efSEd Tanous                 if (ec)
505*1abe55efSEd Tanous                 {
50655c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
507c5b2abe0SLewanczyk, Dawid                     aResp->setErrorStatus();
508c5b2abe0SLewanczyk, Dawid                     return;
509c5b2abe0SLewanczyk, Dawid                 }
510*1abe55efSEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << resp.size()
511*1abe55efSEd Tanous                                  << "led group objects.";
512*1abe55efSEd Tanous                 for (const auto &objPath : resp)
513*1abe55efSEd Tanous                 {
514c5b2abe0SLewanczyk, Dawid                     const std::string &path = objPath.first;
515*1abe55efSEd Tanous                     if (path.rfind("enclosure_identify") != std::string::npos)
516*1abe55efSEd Tanous                     {
517*1abe55efSEd Tanous                         for (const auto &interface : objPath.second)
518*1abe55efSEd Tanous                         {
519*1abe55efSEd Tanous                             if (interface.first ==
520*1abe55efSEd Tanous                                 "xyz.openbmc_project.Led.Group")
521*1abe55efSEd Tanous                             {
522*1abe55efSEd Tanous                                 for (const auto &property : interface.second)
523*1abe55efSEd Tanous                                 {
524*1abe55efSEd Tanous                                     if (property.first == "Asserted")
525*1abe55efSEd Tanous                                     {
526c5b2abe0SLewanczyk, Dawid                                         const bool *asserted =
527*1abe55efSEd Tanous                                             mapbox::getPtr<const bool>(
528*1abe55efSEd Tanous                                                 property.second);
529*1abe55efSEd Tanous                                         if (nullptr != asserted)
530*1abe55efSEd Tanous                                         {
531c5b2abe0SLewanczyk, Dawid                                             callback(*asserted, aResp);
532*1abe55efSEd Tanous                                         }
533*1abe55efSEd Tanous                                         else
534*1abe55efSEd Tanous                                         {
535c5b2abe0SLewanczyk, Dawid                                             callback(false, aResp);
536c5b2abe0SLewanczyk, Dawid                                         }
537c5b2abe0SLewanczyk, Dawid                                     }
538c5b2abe0SLewanczyk, Dawid                                 }
539c5b2abe0SLewanczyk, Dawid                             }
540c5b2abe0SLewanczyk, Dawid                         }
541c5b2abe0SLewanczyk, Dawid                     }
542c5b2abe0SLewanczyk, Dawid                 }
543c5b2abe0SLewanczyk, Dawid             },
544c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.LED.GroupManager",
545*1abe55efSEd Tanous             "/xyz/openbmc_project/led/groups",
546*1abe55efSEd Tanous             "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
547c5b2abe0SLewanczyk, Dawid     }
548c5b2abe0SLewanczyk, Dawid 
549c5b2abe0SLewanczyk, Dawid     template <typename CallbackFunc>
550c5b2abe0SLewanczyk, Dawid     void getLedIdentify(std::shared_ptr<SystemAsyncResp> aResp,
551*1abe55efSEd Tanous                         CallbackFunc &&callback)
552*1abe55efSEd Tanous     {
55355c7b7a2SEd Tanous         BMCWEB_LOG_DEBUG << "Get identify led properties";
55455c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
555*1abe55efSEd Tanous             [aResp{std::move(aResp)},
556*1abe55efSEd Tanous              &callback](const boost::system::error_code ec,
557c5b2abe0SLewanczyk, Dawid                         const PropertiesType &properties) {
558*1abe55efSEd Tanous                 if (ec)
559*1abe55efSEd Tanous                 {
56055c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
561c5b2abe0SLewanczyk, Dawid                     aResp->setErrorStatus();
562c5b2abe0SLewanczyk, Dawid                     return;
563c5b2abe0SLewanczyk, Dawid                 }
564*1abe55efSEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << properties.size()
565*1abe55efSEd Tanous                                  << "led properties.";
566c5b2abe0SLewanczyk, Dawid                 std::string output;
567*1abe55efSEd Tanous                 for (const auto &property : properties)
568*1abe55efSEd Tanous                 {
569*1abe55efSEd Tanous                     if (property.first == "State")
570*1abe55efSEd Tanous                     {
571c5b2abe0SLewanczyk, Dawid                         const std::string *s =
57255c7b7a2SEd Tanous                             mapbox::getPtr<std::string>(property.second);
573*1abe55efSEd Tanous                         if (nullptr != s)
574*1abe55efSEd Tanous                         {
57555c7b7a2SEd Tanous                             BMCWEB_LOG_DEBUG << "Identify Led State: " << *s;
576c5b2abe0SLewanczyk, Dawid                             const auto pos = s->rfind('.');
577*1abe55efSEd Tanous                             if (pos != std::string::npos)
578*1abe55efSEd Tanous                             {
579c5b2abe0SLewanczyk, Dawid                                 auto led = s->substr(pos + 1);
580*1abe55efSEd Tanous                                 for (const std::pair<const char *, const char *>
581*1abe55efSEd Tanous                                          &p :
582*1abe55efSEd Tanous                                      std::array<
583*1abe55efSEd Tanous                                          std::pair<const char *, const char *>,
584*1abe55efSEd Tanous                                          3>{{{"On", "Lit"},
585c5b2abe0SLewanczyk, Dawid                                              {"Blink", "Blinking"},
586*1abe55efSEd Tanous                                              {"Off", "Off"}}})
587*1abe55efSEd Tanous                                 {
588*1abe55efSEd Tanous                                     if (led == p.first)
589*1abe55efSEd Tanous                                     {
590c5b2abe0SLewanczyk, Dawid                                         output = p.second;
591c5b2abe0SLewanczyk, Dawid                                     }
592c5b2abe0SLewanczyk, Dawid                                 }
593c5b2abe0SLewanczyk, Dawid                             }
594c5b2abe0SLewanczyk, Dawid                         }
595c5b2abe0SLewanczyk, Dawid                     }
596c5b2abe0SLewanczyk, Dawid                 }
597c5b2abe0SLewanczyk, Dawid                 callback(output, aResp);
598c5b2abe0SLewanczyk, Dawid             },
599c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.LED.Controller.identify",
600c5b2abe0SLewanczyk, Dawid             "/xyz/openbmc_project/led/physical/identify",
601c5b2abe0SLewanczyk, Dawid             "org.freedesktop.DBus.Properties", "GetAll",
602c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.Led.Physical");
603c5b2abe0SLewanczyk, Dawid     }
604c5b2abe0SLewanczyk, Dawid 
605c5b2abe0SLewanczyk, Dawid     /**
606c5b2abe0SLewanczyk, Dawid      * @brief Retrieves host state properties over dbus
607c5b2abe0SLewanczyk, Dawid      *
608c5b2abe0SLewanczyk, Dawid      * @param[in] aResp     Shared pointer for completing asynchronous calls.
609c5b2abe0SLewanczyk, Dawid      *
610c5b2abe0SLewanczyk, Dawid      * @return None.
611c5b2abe0SLewanczyk, Dawid      */
612*1abe55efSEd Tanous     void getHostState(std::shared_ptr<SystemAsyncResp> aResp)
613*1abe55efSEd Tanous     {
61455c7b7a2SEd Tanous         BMCWEB_LOG_DEBUG << "Get host information.";
61555c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
616c5b2abe0SLewanczyk, Dawid             [aResp{std::move(aResp)}](const boost::system::error_code ec,
617c5b2abe0SLewanczyk, Dawid                                       const PropertiesType &properties) {
618*1abe55efSEd Tanous                 if (ec)
619*1abe55efSEd Tanous                 {
62055c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
621c5b2abe0SLewanczyk, Dawid                     aResp->setErrorStatus();
622c5b2abe0SLewanczyk, Dawid                     return;
623c5b2abe0SLewanczyk, Dawid                 }
624*1abe55efSEd Tanous                 BMCWEB_LOG_DEBUG << "Got " << properties.size()
625*1abe55efSEd Tanous                                  << "host properties.";
626*1abe55efSEd Tanous                 for (const auto &property : properties)
627*1abe55efSEd Tanous                 {
628*1abe55efSEd Tanous                     if (property.first == "CurrentHostState")
629*1abe55efSEd Tanous                     {
630c5b2abe0SLewanczyk, Dawid                         const std::string *s =
63155c7b7a2SEd Tanous                             mapbox::getPtr<const std::string>(property.second);
63255c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "Host state: " << *s;
633*1abe55efSEd Tanous                         if (nullptr != s)
634*1abe55efSEd Tanous                         {
635c5b2abe0SLewanczyk, Dawid                             const auto pos = s->rfind('.');
636*1abe55efSEd Tanous                             if (pos != std::string::npos)
637*1abe55efSEd Tanous                             {
638c5b2abe0SLewanczyk, Dawid                                 // Verify Host State
639*1abe55efSEd Tanous                                 if (s->substr(pos + 1) == "Running")
640*1abe55efSEd Tanous                                 {
64155c7b7a2SEd Tanous                                     aResp->res.jsonValue["PowerState"] = "On";
642*1abe55efSEd Tanous                                     aResp->res.jsonValue["Status"]["State"] =
643*1abe55efSEd Tanous                                         "Enabled";
644*1abe55efSEd Tanous                                 }
645*1abe55efSEd Tanous                                 else
646*1abe55efSEd Tanous                                 {
64755c7b7a2SEd Tanous                                     aResp->res.jsonValue["PowerState"] = "Off";
648*1abe55efSEd Tanous                                     aResp->res.jsonValue["Status"]["State"] =
649*1abe55efSEd Tanous                                         "Disabled";
650c5b2abe0SLewanczyk, Dawid                                 }
651c5b2abe0SLewanczyk, Dawid                             }
652c5b2abe0SLewanczyk, Dawid                         }
653c5b2abe0SLewanczyk, Dawid                     }
654c5b2abe0SLewanczyk, Dawid                 }
655c5b2abe0SLewanczyk, Dawid             },
656*1abe55efSEd Tanous             "xyz.openbmc_project.State.Host",
657*1abe55efSEd Tanous             "/xyz/openbmc_project/state/host0",
658c5b2abe0SLewanczyk, Dawid             "org.freedesktop.DBus.Properties", "GetAll",
659c5b2abe0SLewanczyk, Dawid             "xyz.openbmc_project.State.Host");
660c5b2abe0SLewanczyk, Dawid     }
661c5b2abe0SLewanczyk, Dawid };
662c5b2abe0SLewanczyk, Dawid 
663c5b2abe0SLewanczyk, Dawid /**
664c5b2abe0SLewanczyk, Dawid  * SystemsCollection derived class for delivering ComputerSystems Collection
665c5b2abe0SLewanczyk, Dawid  * Schema
666c5b2abe0SLewanczyk, Dawid  */
667*1abe55efSEd Tanous class SystemsCollection : public Node
668*1abe55efSEd Tanous {
669c5b2abe0SLewanczyk, Dawid   public:
670*1abe55efSEd Tanous     SystemsCollection(CrowApp &app) : Node(app, "/redfish/v1/Systems/")
671*1abe55efSEd Tanous     {
672c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] =
673c5b2abe0SLewanczyk, Dawid             "#ComputerSystemCollection.ComputerSystemCollection";
674c5b2abe0SLewanczyk, Dawid         Node::json["@odata.id"] = "/redfish/v1/Systems";
675c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
676c5b2abe0SLewanczyk, Dawid             "/redfish/v1/"
677c5b2abe0SLewanczyk, Dawid             "$metadata#ComputerSystemCollection.ComputerSystemCollection";
678c5b2abe0SLewanczyk, Dawid         Node::json["Name"] = "Computer System Collection";
679c5b2abe0SLewanczyk, Dawid 
680c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
681c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
682c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
683c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
684c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
685c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
686c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
687c5b2abe0SLewanczyk, Dawid     }
688c5b2abe0SLewanczyk, Dawid 
689c5b2abe0SLewanczyk, Dawid   private:
690c5b2abe0SLewanczyk, Dawid     /**
691c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
692c5b2abe0SLewanczyk, Dawid      */
69355c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
694*1abe55efSEd Tanous                const std::vector<std::string> &params) override
695*1abe55efSEd Tanous     {
696c5b2abe0SLewanczyk, Dawid         // Get board list, and call the below callback for JSON preparation
697*1abe55efSEd Tanous         provider.getBaseboardList([&](const bool &success,
698*1abe55efSEd Tanous                                       const std::vector<std::string> &output) {
699*1abe55efSEd Tanous             if (success)
700*1abe55efSEd Tanous             {
701c5b2abe0SLewanczyk, Dawid                 // ... prepare json array with appropriate @odata.id links
702c5b2abe0SLewanczyk, Dawid                 nlohmann::json boardArray = nlohmann::json::array();
703*1abe55efSEd Tanous                 for (const std::string &boardItem : output)
704*1abe55efSEd Tanous                 {
705c5b2abe0SLewanczyk, Dawid                     boardArray.push_back(
706d76323e5SEd Tanous                         {{"@odata.id", "/redfish/v1/Systems/" + boardItem}});
707c5b2abe0SLewanczyk, Dawid                 }
708c5b2abe0SLewanczyk, Dawid                 // Then attach members, count size and return,
709c5b2abe0SLewanczyk, Dawid                 Node::json["Members"] = boardArray;
710c5b2abe0SLewanczyk, Dawid                 Node::json["Members@odata.count"] = boardArray.size();
71155c7b7a2SEd Tanous                 res.jsonValue = Node::json;
712*1abe55efSEd Tanous             }
713*1abe55efSEd Tanous             else
714*1abe55efSEd Tanous             {
715c5b2abe0SLewanczyk, Dawid                 // ... otherwise, return INTERNALL ERROR
716c5b2abe0SLewanczyk, Dawid                 res.result(boost::beast::http::status::internal_server_error);
717c5b2abe0SLewanczyk, Dawid             }
718c5b2abe0SLewanczyk, Dawid             res.end();
719c5b2abe0SLewanczyk, Dawid         });
720c5b2abe0SLewanczyk, Dawid     }
721c5b2abe0SLewanczyk, Dawid 
722c5b2abe0SLewanczyk, Dawid     OnDemandSystemsProvider provider;
723c5b2abe0SLewanczyk, Dawid };
724c5b2abe0SLewanczyk, Dawid 
725c5b2abe0SLewanczyk, Dawid /**
726c5b2abe0SLewanczyk, Dawid  * Systems override class for delivering ComputerSystems Schema
727c5b2abe0SLewanczyk, Dawid  */
728*1abe55efSEd Tanous class Systems : public Node
729*1abe55efSEd Tanous {
730c5b2abe0SLewanczyk, Dawid   public:
731c5b2abe0SLewanczyk, Dawid     /*
732c5b2abe0SLewanczyk, Dawid      * Default Constructor
733c5b2abe0SLewanczyk, Dawid      */
734*1abe55efSEd Tanous     Systems(CrowApp &app) :
735*1abe55efSEd Tanous         Node(app, "/redfish/v1/Systems/<str>/", std::string())
736*1abe55efSEd Tanous     {
737c5b2abe0SLewanczyk, Dawid         Node::json["@odata.type"] = "#ComputerSystem.v1_3_0.ComputerSystem";
738c5b2abe0SLewanczyk, Dawid         Node::json["@odata.context"] =
739c5b2abe0SLewanczyk, Dawid             "/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
740c5b2abe0SLewanczyk, Dawid         Node::json["SystemType"] = "Physical";
741c5b2abe0SLewanczyk, Dawid         Node::json["Description"] = "Computer System";
742c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideEnabled"] =
743c5b2abe0SLewanczyk, Dawid             "Disabled"; // TODO(Dawid), get real boot data
744c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideTarget"] =
745c5b2abe0SLewanczyk, Dawid             "None"; // TODO(Dawid), get real boot data
746c5b2abe0SLewanczyk, Dawid         Node::json["Boot"]["BootSourceOverrideMode"] =
747c5b2abe0SLewanczyk, Dawid             "Legacy"; // TODO(Dawid), get real boot data
748*1abe55efSEd Tanous         Node::json["Boot"]["BootSourceOverrideTarget@Redfish.AllowableValues"] =
749*1abe55efSEd Tanous             {"None",      "Pxe",       "Hdd", "Cd",
750*1abe55efSEd Tanous              "BiosSetup", "UefiShell", "Usb"}; // TODO(Dawid), get real boot
751*1abe55efSEd Tanous                                                // data
752c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Count"] = int(0);
753c5b2abe0SLewanczyk, Dawid         Node::json["ProcessorSummary"]["Status"]["State"] = "Disabled";
754c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
755c5b2abe0SLewanczyk, Dawid         Node::json["MemorySummary"]["Status"]["State"] = "Disabled";
756c5b2abe0SLewanczyk, Dawid 
757c5b2abe0SLewanczyk, Dawid         entityPrivileges = {
758c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::get, {{"Login"}}},
759c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::head, {{"Login"}}},
760c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
761c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
762c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
763c5b2abe0SLewanczyk, Dawid             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
764c5b2abe0SLewanczyk, Dawid     }
765c5b2abe0SLewanczyk, Dawid 
766c5b2abe0SLewanczyk, Dawid   private:
767c5b2abe0SLewanczyk, Dawid     OnDemandSystemsProvider provider;
768c5b2abe0SLewanczyk, Dawid 
769c5b2abe0SLewanczyk, Dawid     /**
770c5b2abe0SLewanczyk, Dawid      * Functions triggers appropriate requests on DBus
771c5b2abe0SLewanczyk, Dawid      */
77255c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
773*1abe55efSEd Tanous                const std::vector<std::string> &params) override
774*1abe55efSEd Tanous     {
775c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
776c5b2abe0SLewanczyk, Dawid         // impossible
777*1abe55efSEd Tanous         if (params.size() != 1)
778*1abe55efSEd Tanous         {
779c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
780c5b2abe0SLewanczyk, Dawid             res.end();
781c5b2abe0SLewanczyk, Dawid             return;
782c5b2abe0SLewanczyk, Dawid         }
783c5b2abe0SLewanczyk, Dawid 
784c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
785c5b2abe0SLewanczyk, Dawid 
78655c7b7a2SEd Tanous         res.jsonValue = Node::json;
78755c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
788c5b2abe0SLewanczyk, Dawid 
789c5b2abe0SLewanczyk, Dawid         auto asyncResp = std::make_shared<SystemAsyncResp>(res);
790c5b2abe0SLewanczyk, Dawid 
791c5b2abe0SLewanczyk, Dawid         provider.getLedGroupIdentify(
792c5b2abe0SLewanczyk, Dawid             asyncResp, [&](const bool &asserted,
793c5b2abe0SLewanczyk, Dawid                            const std::shared_ptr<SystemAsyncResp> &aResp) {
794*1abe55efSEd Tanous                 if (asserted)
795*1abe55efSEd Tanous                 {
796c5b2abe0SLewanczyk, Dawid                     // If led group is asserted, then another call is needed to
797c5b2abe0SLewanczyk, Dawid                     // get led status
798c5b2abe0SLewanczyk, Dawid                     provider.getLedIdentify(
799*1abe55efSEd Tanous                         aResp,
800*1abe55efSEd Tanous                         [](const std::string &ledStatus,
801c5b2abe0SLewanczyk, Dawid                            const std::shared_ptr<SystemAsyncResp> &aResp) {
802*1abe55efSEd Tanous                             if (!ledStatus.empty())
803*1abe55efSEd Tanous                             {
804*1abe55efSEd Tanous                                 aResp->res.jsonValue["IndicatorLED"] =
805*1abe55efSEd Tanous                                     ledStatus;
806c5b2abe0SLewanczyk, Dawid                             }
807c5b2abe0SLewanczyk, Dawid                         });
808*1abe55efSEd Tanous                 }
809*1abe55efSEd Tanous                 else
810*1abe55efSEd Tanous                 {
81155c7b7a2SEd Tanous                     aResp->res.jsonValue["IndicatorLED"] = "Off";
812c5b2abe0SLewanczyk, Dawid                 }
813c5b2abe0SLewanczyk, Dawid             });
814c5b2abe0SLewanczyk, Dawid         provider.getComputerSystem(asyncResp, name);
815c5b2abe0SLewanczyk, Dawid         provider.getHostState(asyncResp);
816c5b2abe0SLewanczyk, Dawid     }
817c5b2abe0SLewanczyk, Dawid 
81855c7b7a2SEd Tanous     void doPatch(crow::Response &res, const crow::Request &req,
819*1abe55efSEd Tanous                  const std::vector<std::string> &params) override
820*1abe55efSEd Tanous     {
821c5b2abe0SLewanczyk, Dawid         // Check if there is required param, truly entering this shall be
822c5b2abe0SLewanczyk, Dawid         // impossible
823*1abe55efSEd Tanous         if (params.size() != 1)
824*1abe55efSEd Tanous         {
825c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::internal_server_error);
826c5b2abe0SLewanczyk, Dawid             res.end();
827c5b2abe0SLewanczyk, Dawid             return;
828c5b2abe0SLewanczyk, Dawid         }
829c5b2abe0SLewanczyk, Dawid         // Parse JSON request body
830c5b2abe0SLewanczyk, Dawid         nlohmann::json patch;
831*1abe55efSEd Tanous         if (!json_util::processJsonFromRequest(res, req, patch))
832*1abe55efSEd Tanous         {
833c5b2abe0SLewanczyk, Dawid             return;
834c5b2abe0SLewanczyk, Dawid         }
835c5b2abe0SLewanczyk, Dawid         // Find key with new led value
836c5b2abe0SLewanczyk, Dawid         const std::string &name = params[0];
837c5b2abe0SLewanczyk, Dawid         const std::string *reqLedState = nullptr;
838c5b2abe0SLewanczyk, Dawid         json_util::Result r = json_util::getString(
839c5b2abe0SLewanczyk, Dawid             "IndicatorLED", patch, reqLedState,
840c5b2abe0SLewanczyk, Dawid             static_cast<int>(json_util::MessageSetting::TYPE_ERROR) |
841c5b2abe0SLewanczyk, Dawid                 static_cast<int>(json_util::MessageSetting::MISSING),
84255c7b7a2SEd Tanous             res.jsonValue, std::string("/" + name + "/IndicatorLED"));
843*1abe55efSEd Tanous         if ((r != json_util::Result::SUCCESS) || (reqLedState == nullptr))
844*1abe55efSEd Tanous         {
845c5b2abe0SLewanczyk, Dawid             res.result(boost::beast::http::status::bad_request);
846c5b2abe0SLewanczyk, Dawid             res.end();
847c5b2abe0SLewanczyk, Dawid             return;
848c5b2abe0SLewanczyk, Dawid         }
849c5b2abe0SLewanczyk, Dawid         // Verify key value
850c5b2abe0SLewanczyk, Dawid         std::string dbusLedState;
851*1abe55efSEd Tanous         for (const auto &p :
852*1abe55efSEd Tanous              boost::container::flat_map<const char *, const char *>{
853*1abe55efSEd Tanous                  {"On", "Lit"}, {"Blink", "Blinking"}, {"Off", "Off"}})
854*1abe55efSEd Tanous         {
855*1abe55efSEd Tanous             if (*reqLedState == p.second)
856*1abe55efSEd Tanous             {
857c5b2abe0SLewanczyk, Dawid                 dbusLedState = p.first;
858c5b2abe0SLewanczyk, Dawid             }
859c5b2abe0SLewanczyk, Dawid         }
860c5b2abe0SLewanczyk, Dawid 
861c5b2abe0SLewanczyk, Dawid         // Update led status
862c5b2abe0SLewanczyk, Dawid         auto asyncResp = std::make_shared<SystemAsyncResp>(res);
86355c7b7a2SEd Tanous         res.jsonValue = Node::json;
86455c7b7a2SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
865c5b2abe0SLewanczyk, Dawid 
866c5b2abe0SLewanczyk, Dawid         provider.getHostState(asyncResp);
867c5b2abe0SLewanczyk, Dawid         provider.getComputerSystem(asyncResp, name);
868c5b2abe0SLewanczyk, Dawid 
869*1abe55efSEd Tanous         if (dbusLedState.empty())
870*1abe55efSEd Tanous         {
871c5b2abe0SLewanczyk, Dawid             messages::addMessageToJsonRoot(
87255c7b7a2SEd Tanous                 res.jsonValue,
873c5b2abe0SLewanczyk, Dawid                 messages::propertyValueNotInList(*reqLedState, "IndicatorLED"));
874*1abe55efSEd Tanous         }
875*1abe55efSEd Tanous         else
876*1abe55efSEd Tanous         {
877c5b2abe0SLewanczyk, Dawid             // Update led group
87855c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Update led group.";
87955c7b7a2SEd Tanous             crow::connections::systemBus->async_method_call(
880c5b2abe0SLewanczyk, Dawid                 [&, asyncResp{std::move(asyncResp)}](
881c5b2abe0SLewanczyk, Dawid                     const boost::system::error_code ec) {
882*1abe55efSEd Tanous                     if (ec)
883*1abe55efSEd Tanous                     {
88455c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
885c5b2abe0SLewanczyk, Dawid                         asyncResp->setErrorStatus();
886c5b2abe0SLewanczyk, Dawid                         return;
887c5b2abe0SLewanczyk, Dawid                     }
88855c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Led group update done.";
889c5b2abe0SLewanczyk, Dawid                 },
890c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.LED.GroupManager",
891c5b2abe0SLewanczyk, Dawid                 "/xyz/openbmc_project/led/groups/enclosure_identify",
892c5b2abe0SLewanczyk, Dawid                 "org.freedesktop.DBus.Properties", "Set",
893c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Led.Group", "Asserted",
894c5b2abe0SLewanczyk, Dawid                 sdbusplus::message::variant<bool>(
895c5b2abe0SLewanczyk, Dawid                     (dbusLedState == "Off" ? false : true)));
896c5b2abe0SLewanczyk, Dawid             // Update identify led status
89755c7b7a2SEd Tanous             BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
89855c7b7a2SEd Tanous             crow::connections::systemBus->async_method_call(
899c5b2abe0SLewanczyk, Dawid                 [&, asyncResp{std::move(asyncResp)}](
900c5b2abe0SLewanczyk, Dawid                     const boost::system::error_code ec) {
901*1abe55efSEd Tanous                     if (ec)
902*1abe55efSEd Tanous                     {
90355c7b7a2SEd Tanous                         BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
904c5b2abe0SLewanczyk, Dawid                         asyncResp->setErrorStatus();
905c5b2abe0SLewanczyk, Dawid                         return;
906c5b2abe0SLewanczyk, Dawid                     }
90755c7b7a2SEd Tanous                     BMCWEB_LOG_DEBUG << "Led state update done.";
90855c7b7a2SEd Tanous                     res.jsonValue["IndicatorLED"] = *reqLedState;
909c5b2abe0SLewanczyk, Dawid                 },
910c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.LED.Controller.identify",
911c5b2abe0SLewanczyk, Dawid                 "/xyz/openbmc_project/led/physical/identify",
912c5b2abe0SLewanczyk, Dawid                 "org.freedesktop.DBus.Properties", "Set",
913c5b2abe0SLewanczyk, Dawid                 "xyz.openbmc_project.Led.Physical", "State",
914c5b2abe0SLewanczyk, Dawid                 sdbusplus::message::variant<std::string>(
915c5b2abe0SLewanczyk, Dawid                     "xyz.openbmc_project.Led.Physical.Action." + dbusLedState));
916c5b2abe0SLewanczyk, Dawid         }
917c5b2abe0SLewanczyk, Dawid     }
918c5b2abe0SLewanczyk, Dawid };
919c5b2abe0SLewanczyk, Dawid } // namespace redfish
920