blob: 59987fb0701a1f477f9691a145defd5097e1b75b [file] [log] [blame]
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +01001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
James Feistb49ac872019-05-21 15:12:01 -070018#include "health.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080019#include "led.hpp"
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010020#include "node.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070021
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010022#include <boost/container/flat_map.hpp>
Ed Tanousabf2add2019-01-22 16:40:12 -080023#include <variant>
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010024
Ed Tanous1abe55e2018-09-05 08:30:59 -070025namespace redfish
26{
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010027
28/**
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060029 * @brief Retrieves chassis state properties over dbus
30 *
31 * @param[in] aResp - Shared pointer for completing asynchronous calls.
32 *
33 * @return None.
34 */
35void getChassisState(std::shared_ptr<AsyncResp> aResp)
36{
37 crow::connections::systemBus->async_method_call(
38 [aResp{std::move(aResp)}](
39 const boost::system::error_code ec,
40 const std::variant<std::string> &chassisState) {
41 if (ec)
42 {
43 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
44 messages::internalError(aResp->res);
45 return;
46 }
47
48 const std::string *s = std::get_if<std::string>(&chassisState);
49 BMCWEB_LOG_DEBUG << "Chassis state: " << *s;
50 if (s != nullptr)
51 {
52 // Verify Chassis State
53 if (*s == "xyz.openbmc_project.State.Chassis.PowerState.On")
54 {
55 aResp->res.jsonValue["PowerState"] = "On";
56 aResp->res.jsonValue["Status"]["State"] = "Enabled";
57 }
58 else if (*s ==
59 "xyz.openbmc_project.State.Chassis.PowerState.Off")
60 {
61 aResp->res.jsonValue["PowerState"] = "Off";
62 aResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
63 }
64 }
65 },
66 "xyz.openbmc_project.State.Chassis",
67 "/xyz/openbmc_project/state/chassis0",
68 "org.freedesktop.DBus.Properties", "Get",
69 "xyz.openbmc_project.State.Chassis", "CurrentPowerState");
70}
71
72/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010073 * DBus types primitives for several generic DBus interfaces
74 * TODO(Pawel) consider move this to separate file into boost::dbus
75 */
Ed Tanous55c7b7a2018-05-22 15:27:24 -070076// Note, this is not a very useful Variant, but because it isn't used to get
Ed Tanousaa2e59c2018-04-12 12:17:20 -070077// values, it should be as simple as possible
78// TODO(ed) invent a nullvariant type
Cheng C Yang5fd7ba62019-11-28 15:58:08 +080079using VariantType = std::variant<bool, std::string, uint64_t, uint32_t>;
Ed Tanousaa2e59c2018-04-12 12:17:20 -070080using ManagedObjectsType = std::vector<std::pair<
81 sdbusplus::message::object_path,
82 std::vector<std::pair<std::string,
83 std::vector<std::pair<std::string, VariantType>>>>>>;
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010084
Ed Tanousaa2e59c2018-04-12 12:17:20 -070085using PropertiesType = boost::container::flat_map<std::string, VariantType>;
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010086
Qiang XUc1819422019-02-27 13:51:32 +080087void getIntrusionByService(std::shared_ptr<AsyncResp> aResp,
88 const std::string &service,
89 const std::string &objPath)
90{
91 BMCWEB_LOG_DEBUG << "Get intrusion status by service \n";
92
93 crow::connections::systemBus->async_method_call(
94 [aResp{std::move(aResp)}](const boost::system::error_code ec,
95 const std::variant<std::string> &value) {
96 if (ec)
97 {
98 // do not add err msg in redfish response, becaues this is not
99 // mandatory property
100 BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n";
101 return;
102 }
103
104 const std::string *status = std::get_if<std::string>(&value);
105
106 if (status == nullptr)
107 {
108 BMCWEB_LOG_ERROR << "intrusion status read error \n";
109 return;
110 }
111
112 aResp->res.jsonValue["PhysicalSecurity"] = {
113 {"IntrusionSensorNumber", 1}, {"IntrusionSensor", *status}};
114 },
115 service, objPath, "org.freedesktop.DBus.Properties", "Get",
116 "xyz.openbmc_project.Chassis.Intrusion", "Status");
117}
118
119/**
120 * Retrieves physical security properties over dbus
121 */
122void getPhysicalSecurityData(std::shared_ptr<AsyncResp> aResp)
123{
124 crow::connections::systemBus->async_method_call(
125 [aResp{std::move(aResp)}](
126 const boost::system::error_code ec,
127 const std::vector<std::pair<
128 std::string,
129 std::vector<std::pair<std::string, std::vector<std::string>>>>>
130 &subtree) {
131 if (ec)
132 {
133 // do not add err msg in redfish response, becaues this is not
134 // mandatory property
135 BMCWEB_LOG_ERROR << "DBUS error: no matched iface " << ec
136 << "\n";
137 return;
138 }
139 // Iterate over all retrieved ObjectPaths.
140 for (const auto &object : subtree)
141 {
142 for (const auto &service : object.second)
143 {
144 getIntrusionByService(aResp, service.first, object.first);
145 return;
146 }
147 }
148 },
149 "xyz.openbmc_project.ObjectMapper",
150 "/xyz/openbmc_project/object_mapper",
151 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700152 "/xyz/openbmc_project/Intrusion", 1,
Qiang XUc1819422019-02-27 13:51:32 +0800153 std::array<const char *, 1>{"xyz.openbmc_project.Chassis.Intrusion"});
154}
155
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100156/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100157 * ChassisCollection derived class for delivering Chassis Collection Schema
158 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700159class ChassisCollection : public Node
160{
161 public:
162 ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/")
163 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700164 entityPrivileges = {
165 {boost::beast::http::verb::get, {{"Login"}}},
166 {boost::beast::http::verb::head, {{"Login"}}},
167 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
168 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
169 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
170 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
171 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100172
Ed Tanous1abe55e2018-09-05 08:30:59 -0700173 private:
174 /**
175 * Functions triggers appropriate requests on DBus
176 */
177 void doGet(crow::Response &res, const crow::Request &req,
178 const std::vector<std::string> &params) override
179 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800180 res.jsonValue["@odata.type"] = "#ChassisCollection.ChassisCollection";
181 res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
182 res.jsonValue["@odata.context"] =
183 "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
184 res.jsonValue["Name"] = "Chassis Collection";
185
Shawn McCarneyadc4f0d2019-07-24 09:21:50 -0500186 const std::array<const char *, 2> interfaces = {
Gunnar Mills603a6642019-01-21 17:03:51 -0600187 "xyz.openbmc_project.Inventory.Item.Board",
Shawn McCarneyadc4f0d2019-07-24 09:21:50 -0500188 "xyz.openbmc_project.Inventory.Item.Chassis"};
Gunnar Mills603a6642019-01-21 17:03:51 -0600189
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700190 auto asyncResp = std::make_shared<AsyncResp>(res);
191 crow::connections::systemBus->async_method_call(
192 [asyncResp](const boost::system::error_code ec,
193 const std::vector<std::string> &chassisList) {
194 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700195 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700196 messages::internalError(asyncResp->res);
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700197 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700198 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700199 nlohmann::json &chassisArray =
200 asyncResp->res.jsonValue["Members"];
201 chassisArray = nlohmann::json::array();
202 for (const std::string &objpath : chassisList)
203 {
204 std::size_t lastPos = objpath.rfind("/");
205 if (lastPos == std::string::npos)
206 {
207 BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
208 continue;
209 }
210 chassisArray.push_back(
211 {{"@odata.id", "/redfish/v1/Chassis/" +
212 objpath.substr(lastPos + 1)}});
213 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100214
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700215 asyncResp->res.jsonValue["Members@odata.count"] =
216 chassisArray.size();
217 },
218 "xyz.openbmc_project.ObjectMapper",
219 "/xyz/openbmc_project/object_mapper",
220 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
Ed Tanous271584a2019-07-09 16:24:22 -0700221 "/xyz/openbmc_project/inventory", 0, interfaces);
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700222 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100223};
224
225/**
226 * Chassis override class for delivering Chassis Schema
227 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700228class Chassis : public Node
229{
230 public:
231 Chassis(CrowApp &app) :
232 Node(app, "/redfish/v1/Chassis/<str>/", std::string())
233 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700234 entityPrivileges = {
235 {boost::beast::http::verb::get, {{"Login"}}},
236 {boost::beast::http::verb::head, {{"Login"}}},
237 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
238 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
239 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
240 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100241 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100242
Ed Tanous1abe55e2018-09-05 08:30:59 -0700243 private:
244 /**
245 * Functions triggers appropriate requests on DBus
246 */
247 void doGet(crow::Response &res, const crow::Request &req,
248 const std::vector<std::string> &params) override
249 {
Shawn McCarneyadc4f0d2019-07-24 09:21:50 -0500250 const std::array<const char *, 2> interfaces = {
Gunnar Mills734bfe92019-01-21 16:33:50 -0600251 "xyz.openbmc_project.Inventory.Item.Board",
Shawn McCarneyadc4f0d2019-07-24 09:21:50 -0500252 "xyz.openbmc_project.Inventory.Item.Chassis"};
Gunnar Mills734bfe92019-01-21 16:33:50 -0600253
Ed Tanous1abe55e2018-09-05 08:30:59 -0700254 // Check if there is required param, truly entering this shall be
255 // impossible.
256 if (params.size() != 1)
257 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700258 messages::internalError(res);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700259 res.end();
260 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700261 }
Shawn McCarney99cffd72019-03-01 10:46:20 -0600262 const std::string &chassisId = params[0];
Ed Tanouse0d918b2018-03-27 17:41:04 -0700263
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700264 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700265 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700266 [asyncResp, chassisId(std::string(chassisId))](
267 const boost::system::error_code ec,
James Feist1c8fba92019-12-20 15:12:07 -0800268 const crow::openbmc_mapper::GetSubTreeType &subtree) {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700269 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700270 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700271 messages::internalError(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700272 return;
273 }
274 // Iterate over all retrieved ObjectPaths.
275 for (const std::pair<
276 std::string,
277 std::vector<
278 std::pair<std::string, std::vector<std::string>>>>
279 &object : subtree)
280 {
281 const std::string &path = object.first;
282 const std::vector<
283 std::pair<std::string, std::vector<std::string>>>
284 &connectionNames = object.second;
Ed Tanouse0d918b2018-03-27 17:41:04 -0700285
Ed Tanous1abe55e2018-09-05 08:30:59 -0700286 if (!boost::ends_with(path, chassisId))
287 {
288 continue;
Ed Tanousdaf36e22018-04-20 16:01:36 -0700289 }
Shawn McCarney26f03892019-05-03 13:20:24 -0500290
James Feistb49ac872019-05-21 15:12:01 -0700291 auto health = std::make_shared<HealthPopulate>(asyncResp);
292
293 crow::connections::systemBus->async_method_call(
294 [health](const boost::system::error_code ec,
295 std::variant<std::vector<std::string>> &resp) {
296 if (ec)
297 {
298 return; // no sensors = no failures
299 }
300 std::vector<std::string> *data =
301 std::get_if<std::vector<std::string>>(&resp);
302 if (data == nullptr)
303 {
304 return;
305 }
306 health->inventory = std::move(*data);
307 },
308 "xyz.openbmc_project.ObjectMapper",
309 path + "/all_sensors",
310 "org.freedesktop.DBus.Properties", "Get",
311 "xyz.openbmc_project.Association", "endpoints");
312
313 health->populate();
314
Ed Tanous1abe55e2018-09-05 08:30:59 -0700315 if (connectionNames.size() < 1)
316 {
James Feist1c8fba92019-12-20 15:12:07 -0800317 BMCWEB_LOG_ERROR << "Got 0 Connection names";
Ed Tanous1abe55e2018-09-05 08:30:59 -0700318 continue;
319 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700320
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700321 asyncResp->res.jsonValue["@odata.type"] =
Jason M. Billsadbe1922019-10-14 15:44:35 -0700322 "#Chassis.v1_10_0.Chassis";
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700323 asyncResp->res.jsonValue["@odata.id"] =
324 "/redfish/v1/Chassis/" + chassisId;
325 asyncResp->res.jsonValue["@odata.context"] =
326 "/redfish/v1/$metadata#Chassis.Chassis";
327 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
328 asyncResp->res.jsonValue["ChassisType"] = "RackMount";
Jason M. Billsadbe1922019-10-14 15:44:35 -0700329 asyncResp->res.jsonValue["PCIeDevices"] = {
330 {"@odata.id",
331 "/redfish/v1/Systems/system/PCIeDevices"}};
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700332
333 const std::string &connectionName =
334 connectionNames[0].first;
James Feist1c8fba92019-12-20 15:12:07 -0800335
336 const std::vector<std::string> &interfaces =
337 connectionNames[0].second;
338 const std::array<const char *, 2> hasIndicatorLed = {
339 "xyz.openbmc_project.Inventory.Item.Panel",
340 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
341
342 for (const char *interface : hasIndicatorLed)
343 {
344 if (std::find(interfaces.begin(), interfaces.end(),
345 interface) != interfaces.end())
346 {
347 getIndicatorLedState(asyncResp);
348 break;
349 }
350 }
351
Ed Tanous1abe55e2018-09-05 08:30:59 -0700352 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700353 [asyncResp, chassisId(std::string(chassisId))](
354 const boost::system::error_code ec,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700355 const std::vector<std::pair<
356 std::string, VariantType>> &propertiesList) {
357 for (const std::pair<std::string, VariantType>
358 &property : propertiesList)
359 {
Shawn McCarney99cffd72019-03-01 10:46:20 -0600360 // Store DBus properties that are also Redfish
361 // properties with same name and a string value
362 const std::string &propertyName =
363 property.first;
364 if ((propertyName == "PartNumber") ||
365 (propertyName == "SerialNumber") ||
366 (propertyName == "Manufacturer") ||
367 (propertyName == "Model"))
Ed Tanous1abe55e2018-09-05 08:30:59 -0700368 {
Shawn McCarney99cffd72019-03-01 10:46:20 -0600369 const std::string *value =
370 std::get_if<std::string>(
371 &property.second);
372 if (value != nullptr)
373 {
374 asyncResp->res.jsonValue[propertyName] =
375 *value;
376 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700377 }
378 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700379 asyncResp->res.jsonValue["Name"] = chassisId;
380 asyncResp->res.jsonValue["Id"] = chassisId;
381 asyncResp->res.jsonValue["Thermal"] = {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700382 {"@odata.id", "/redfish/v1/Chassis/" +
383 chassisId + "/Thermal"}};
Ed Tanous2474adf2018-09-05 16:31:16 -0700384 // Power object
385 asyncResp->res.jsonValue["Power"] = {
386 {"@odata.id", "/redfish/v1/Chassis/" +
387 chassisId + "/Power"}};
Anthony Wilson95a3eca2019-06-11 10:44:47 -0500388 // SensorCollection
389 asyncResp->res.jsonValue["Sensors"] = {
390 {"@odata.id", "/redfish/v1/Chassis/" +
391 chassisId + "/Sensors"}};
Ed Tanous029573d2019-02-01 10:57:49 -0800392 asyncResp->res.jsonValue["Status"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800393 {"State", "Enabled"},
394 };
Ed Tanous2474adf2018-09-05 16:31:16 -0700395
Ed Tanous029573d2019-02-01 10:57:49 -0800396 asyncResp->res
397 .jsonValue["Links"]["ComputerSystems"] = {
398 {{"@odata.id", "/redfish/v1/Systems/system"}}};
399 asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
400 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600401 getChassisState(asyncResp);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700402 },
403 connectionName, path, "org.freedesktop.DBus.Properties",
404 "GetAll",
405 "xyz.openbmc_project.Inventory.Decorator.Asset");
Ed Tanous1abe55e2018-09-05 08:30:59 -0700406 return;
407 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700408
Ed Tanous1abe55e2018-09-05 08:30:59 -0700409 // Couldn't find an object with that name. return an error
Jason M. Billsf12894f2018-10-09 12:45:45 -0700410 messages::resourceNotFound(
Jason M. Billsadbe1922019-10-14 15:44:35 -0700411 asyncResp->res, "#Chassis.v1_10_0.Chassis", chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700412 },
413 "xyz.openbmc_project.ObjectMapper",
414 "/xyz/openbmc_project/object_mapper",
415 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700416 "/xyz/openbmc_project/inventory", 0, interfaces);
Qiang XUc1819422019-02-27 13:51:32 +0800417
418 getPhysicalSecurityData(asyncResp);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700419 }
James Feist1c8fba92019-12-20 15:12:07 -0800420
421 void doPatch(crow::Response &res, const crow::Request &req,
422 const std::vector<std::string> &params) override
423 {
424 std::optional<std::string> indicatorLed;
425 auto asyncResp = std::make_shared<AsyncResp>(res);
426
427 if (params.size() != 1)
428 {
429 return;
430 }
431
432 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed))
433 {
434 return;
435 }
436
437 if (!indicatorLed)
438 {
439 return; // delete this when we support more patch properties
440 }
441
442 const std::array<const char *, 2> interfaces = {
443 "xyz.openbmc_project.Inventory.Item.Board",
444 "xyz.openbmc_project.Inventory.Item.Chassis"};
445
446 const std::string &chassisId = params[0];
447
448 crow::connections::systemBus->async_method_call(
449 [asyncResp, chassisId, indicatorLed](
450 const boost::system::error_code ec,
451 const crow::openbmc_mapper::GetSubTreeType &subtree) {
452 if (ec)
453 {
454 messages::internalError(asyncResp->res);
455 return;
456 }
457
458 // Iterate over all retrieved ObjectPaths.
459 for (const std::pair<
460 std::string,
461 std::vector<
462 std::pair<std::string, std::vector<std::string>>>>
463 &object : subtree)
464 {
465 const std::string &path = object.first;
466 const std::vector<
467 std::pair<std::string, std::vector<std::string>>>
468 &connectionNames = object.second;
469
470 if (!boost::ends_with(path, chassisId))
471 {
472 continue;
473 }
474
475 if (connectionNames.size() < 1)
476 {
477 BMCWEB_LOG_ERROR << "Got 0 Connection names";
478 continue;
479 }
480
481 const std::vector<std::string> &interfaces =
482 connectionNames[0].second;
483
484 if (indicatorLed)
485 {
486 const std::array<const char *, 2> hasIndicatorLed = {
487 "xyz.openbmc_project.Inventory.Item.Panel",
488 "xyz.openbmc_project.Inventory.Item.Board."
489 "Motherboard"};
490 bool indicatorChassis = false;
491 for (const char *interface : hasIndicatorLed)
492 {
493 if (std::find(interfaces.begin(), interfaces.end(),
494 interface) != interfaces.end())
495 {
496 indicatorChassis = true;
497 break;
498 }
499 }
500 if (indicatorChassis)
501 {
502 setIndicatorLedState(asyncResp,
503 std::move(*indicatorLed));
504 }
505 else
506 {
507 messages::propertyUnknown(asyncResp->res,
508 "IndicatorLED");
509 }
510 }
511 return;
512 }
513
514 messages::resourceNotFound(
515 asyncResp->res, "#Chassis.v1_10_0.Chassis", chassisId);
516 },
517 "xyz.openbmc_project.ObjectMapper",
518 "/xyz/openbmc_project/object_mapper",
519 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
520 "/xyz/openbmc_project/inventory", 0, interfaces);
521 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700522};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700523} // namespace redfish