blob: 2b098a93fa51804f1f7899b673ce0c88fa87dc50 [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>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050023
Ed Tanousabf2add2019-01-22 16:40:12 -080024#include <variant>
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010025
Ed Tanous1abe55e2018-09-05 08:30:59 -070026namespace redfish
27{
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010028
29/**
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060030 * @brief Retrieves chassis state properties over dbus
31 *
32 * @param[in] aResp - Shared pointer for completing asynchronous calls.
33 *
34 * @return None.
35 */
36void getChassisState(std::shared_ptr<AsyncResp> aResp)
37{
38 crow::connections::systemBus->async_method_call(
39 [aResp{std::move(aResp)}](
40 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050041 const std::variant<std::string>& chassisState) {
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060042 if (ec)
43 {
44 BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
45 messages::internalError(aResp->res);
46 return;
47 }
48
Gunnar Mills1214b7e2020-06-04 10:11:30 -050049 const std::string* s = std::get_if<std::string>(&chassisState);
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060050 BMCWEB_LOG_DEBUG << "Chassis state: " << *s;
51 if (s != nullptr)
52 {
53 // Verify Chassis State
54 if (*s == "xyz.openbmc_project.State.Chassis.PowerState.On")
55 {
56 aResp->res.jsonValue["PowerState"] = "On";
57 aResp->res.jsonValue["Status"]["State"] = "Enabled";
58 }
59 else if (*s ==
60 "xyz.openbmc_project.State.Chassis.PowerState.Off")
61 {
62 aResp->res.jsonValue["PowerState"] = "Off";
63 aResp->res.jsonValue["Status"]["State"] = "StandbyOffline";
64 }
65 }
66 },
67 "xyz.openbmc_project.State.Chassis",
68 "/xyz/openbmc_project/state/chassis0",
69 "org.freedesktop.DBus.Properties", "Get",
70 "xyz.openbmc_project.State.Chassis", "CurrentPowerState");
71}
72
73/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010074 * DBus types primitives for several generic DBus interfaces
75 * TODO(Pawel) consider move this to separate file into boost::dbus
76 */
Ed Tanous55c7b7a2018-05-22 15:27:24 -070077// Note, this is not a very useful Variant, but because it isn't used to get
Ed Tanousaa2e59c2018-04-12 12:17:20 -070078// values, it should be as simple as possible
79// TODO(ed) invent a nullvariant type
Cheng C Yang5fd7ba62019-11-28 15:58:08 +080080using VariantType = std::variant<bool, std::string, uint64_t, uint32_t>;
Ed Tanousaa2e59c2018-04-12 12:17:20 -070081using ManagedObjectsType = std::vector<std::pair<
82 sdbusplus::message::object_path,
83 std::vector<std::pair<std::string,
84 std::vector<std::pair<std::string, VariantType>>>>>>;
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010085
Ed Tanousaa2e59c2018-04-12 12:17:20 -070086using PropertiesType = boost::container::flat_map<std::string, VariantType>;
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010087
Qiang XUc1819422019-02-27 13:51:32 +080088void getIntrusionByService(std::shared_ptr<AsyncResp> aResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050089 const std::string& service,
90 const std::string& objPath)
Qiang XUc1819422019-02-27 13:51:32 +080091{
92 BMCWEB_LOG_DEBUG << "Get intrusion status by service \n";
93
94 crow::connections::systemBus->async_method_call(
95 [aResp{std::move(aResp)}](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -050096 const std::variant<std::string>& value) {
Qiang XUc1819422019-02-27 13:51:32 +080097 if (ec)
98 {
99 // do not add err msg in redfish response, becaues this is not
100 // mandatory property
101 BMCWEB_LOG_ERROR << "DBUS response error " << ec << "\n";
102 return;
103 }
104
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500105 const std::string* status = std::get_if<std::string>(&value);
Qiang XUc1819422019-02-27 13:51:32 +0800106
107 if (status == nullptr)
108 {
109 BMCWEB_LOG_ERROR << "intrusion status read error \n";
110 return;
111 }
112
113 aResp->res.jsonValue["PhysicalSecurity"] = {
114 {"IntrusionSensorNumber", 1}, {"IntrusionSensor", *status}};
115 },
116 service, objPath, "org.freedesktop.DBus.Properties", "Get",
117 "xyz.openbmc_project.Chassis.Intrusion", "Status");
118}
119
120/**
121 * Retrieves physical security properties over dbus
122 */
123void getPhysicalSecurityData(std::shared_ptr<AsyncResp> aResp)
124{
125 crow::connections::systemBus->async_method_call(
126 [aResp{std::move(aResp)}](
127 const boost::system::error_code ec,
128 const std::vector<std::pair<
129 std::string,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500130 std::vector<std::pair<std::string, std::vector<std::string>>>>>&
131 subtree) {
Qiang XUc1819422019-02-27 13:51:32 +0800132 if (ec)
133 {
134 // do not add err msg in redfish response, becaues this is not
135 // mandatory property
136 BMCWEB_LOG_ERROR << "DBUS error: no matched iface " << ec
137 << "\n";
138 return;
139 }
140 // Iterate over all retrieved ObjectPaths.
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500141 for (const auto& object : subtree)
Qiang XUc1819422019-02-27 13:51:32 +0800142 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500143 for (const auto& service : object.second)
Qiang XUc1819422019-02-27 13:51:32 +0800144 {
145 getIntrusionByService(aResp, service.first, object.first);
146 return;
147 }
148 }
149 },
150 "xyz.openbmc_project.ObjectMapper",
151 "/xyz/openbmc_project/object_mapper",
152 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700153 "/xyz/openbmc_project/Intrusion", 1,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500154 std::array<const char*, 1>{"xyz.openbmc_project.Chassis.Intrusion"});
Qiang XUc1819422019-02-27 13:51:32 +0800155}
156
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100157/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100158 * ChassisCollection derived class for delivering Chassis Collection Schema
159 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700160class ChassisCollection : public Node
161{
162 public:
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500163 ChassisCollection(CrowApp& app) : Node(app, "/redfish/v1/Chassis/")
Ed Tanous1abe55e2018-09-05 08:30:59 -0700164 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700165 entityPrivileges = {
166 {boost::beast::http::verb::get, {{"Login"}}},
167 {boost::beast::http::verb::head, {{"Login"}}},
168 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
169 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
170 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
171 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
172 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100173
Ed Tanous1abe55e2018-09-05 08:30:59 -0700174 private:
175 /**
176 * Functions triggers appropriate requests on DBus
177 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500178 void doGet(crow::Response& res, const crow::Request& req,
179 const std::vector<std::string>& params) override
Ed Tanous1abe55e2018-09-05 08:30:59 -0700180 {
Ed Tanous0f74e642018-11-12 15:17:05 -0800181 res.jsonValue["@odata.type"] = "#ChassisCollection.ChassisCollection";
182 res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
Ed Tanous0f74e642018-11-12 15:17:05 -0800183 res.jsonValue["Name"] = "Chassis Collection";
184
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500185 const std::array<const char*, 2> interfaces = {
Gunnar Mills603a6642019-01-21 17:03:51 -0600186 "xyz.openbmc_project.Inventory.Item.Board",
Shawn McCarneyadc4f0d2019-07-24 09:21:50 -0500187 "xyz.openbmc_project.Inventory.Item.Chassis"};
Gunnar Mills603a6642019-01-21 17:03:51 -0600188
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700189 auto asyncResp = std::make_shared<AsyncResp>(res);
190 crow::connections::systemBus->async_method_call(
191 [asyncResp](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500192 const std::vector<std::string>& chassisList) {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700193 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700194 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700195 messages::internalError(asyncResp->res);
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700196 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700197 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500198 nlohmann::json& chassisArray =
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700199 asyncResp->res.jsonValue["Members"];
200 chassisArray = nlohmann::json::array();
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500201 for (const std::string& objpath : chassisList)
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700202 {
203 std::size_t lastPos = objpath.rfind("/");
204 if (lastPos == std::string::npos)
205 {
206 BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
207 continue;
208 }
209 chassisArray.push_back(
210 {{"@odata.id", "/redfish/v1/Chassis/" +
211 objpath.substr(lastPos + 1)}});
212 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100213
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700214 asyncResp->res.jsonValue["Members@odata.count"] =
215 chassisArray.size();
216 },
217 "xyz.openbmc_project.ObjectMapper",
218 "/xyz/openbmc_project/object_mapper",
219 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
Ed Tanous271584a2019-07-09 16:24:22 -0700220 "/xyz/openbmc_project/inventory", 0, interfaces);
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700221 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100222};
223
224/**
225 * Chassis override class for delivering Chassis Schema
226 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700227class Chassis : public Node
228{
229 public:
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500230 Chassis(CrowApp& app) :
Ed Tanous1abe55e2018-09-05 08:30:59 -0700231 Node(app, "/redfish/v1/Chassis/<str>/", std::string())
232 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700233 entityPrivileges = {
234 {boost::beast::http::verb::get, {{"Login"}}},
235 {boost::beast::http::verb::head, {{"Login"}}},
236 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
237 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
238 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
239 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100240 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100241
Ed Tanous1abe55e2018-09-05 08:30:59 -0700242 private:
243 /**
244 * Functions triggers appropriate requests on DBus
245 */
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500246 void doGet(crow::Response& res, const crow::Request& req,
247 const std::vector<std::string>& params) override
Ed Tanous1abe55e2018-09-05 08:30:59 -0700248 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500249 const std::array<const char*, 2> interfaces = {
Gunnar Mills734bfe92019-01-21 16:33:50 -0600250 "xyz.openbmc_project.Inventory.Item.Board",
Shawn McCarneyadc4f0d2019-07-24 09:21:50 -0500251 "xyz.openbmc_project.Inventory.Item.Chassis"};
Gunnar Mills734bfe92019-01-21 16:33:50 -0600252
Ed Tanous1abe55e2018-09-05 08:30:59 -0700253 // Check if there is required param, truly entering this shall be
254 // impossible.
255 if (params.size() != 1)
256 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700257 messages::internalError(res);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700258 res.end();
259 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700260 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500261 const std::string& chassisId = params[0];
Ed Tanouse0d918b2018-03-27 17:41:04 -0700262
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700263 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700264 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700265 [asyncResp, chassisId(std::string(chassisId))](
266 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500267 const crow::openbmc_mapper::GetSubTreeType& subtree) {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700268 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700269 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700270 messages::internalError(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700271 return;
272 }
273 // Iterate over all retrieved ObjectPaths.
274 for (const std::pair<
275 std::string,
276 std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500277 std::pair<std::string, std::vector<std::string>>>>&
278 object : subtree)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700279 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500280 const std::string& path = object.first;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700281 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500282 std::pair<std::string, std::vector<std::string>>>&
283 connectionNames = object.second;
Ed Tanouse0d918b2018-03-27 17:41:04 -0700284
Ed Tanous1abe55e2018-09-05 08:30:59 -0700285 if (!boost::ends_with(path, chassisId))
286 {
287 continue;
Ed Tanousdaf36e22018-04-20 16:01:36 -0700288 }
Shawn McCarney26f03892019-05-03 13:20:24 -0500289
James Feistb49ac872019-05-21 15:12:01 -0700290 auto health = std::make_shared<HealthPopulate>(asyncResp);
291
292 crow::connections::systemBus->async_method_call(
293 [health](const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500294 std::variant<std::vector<std::string>>& resp) {
James Feistb49ac872019-05-21 15:12:01 -0700295 if (ec)
296 {
297 return; // no sensors = no failures
298 }
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500299 std::vector<std::string>* data =
James Feistb49ac872019-05-21 15:12:01 -0700300 std::get_if<std::vector<std::string>>(&resp);
301 if (data == nullptr)
302 {
303 return;
304 }
305 health->inventory = std::move(*data);
306 },
307 "xyz.openbmc_project.ObjectMapper",
308 path + "/all_sensors",
309 "org.freedesktop.DBus.Properties", "Get",
310 "xyz.openbmc_project.Association", "endpoints");
311
312 health->populate();
313
Ed Tanous1abe55e2018-09-05 08:30:59 -0700314 if (connectionNames.size() < 1)
315 {
James Feist1c8fba92019-12-20 15:12:07 -0800316 BMCWEB_LOG_ERROR << "Got 0 Connection names";
Ed Tanous1abe55e2018-09-05 08:30:59 -0700317 continue;
318 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700319
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700320 asyncResp->res.jsonValue["@odata.type"] =
Jason M. Billsadbe1922019-10-14 15:44:35 -0700321 "#Chassis.v1_10_0.Chassis";
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700322 asyncResp->res.jsonValue["@odata.id"] =
323 "/redfish/v1/Chassis/" + chassisId;
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700324 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
325 asyncResp->res.jsonValue["ChassisType"] = "RackMount";
Jason M. Billsadbe1922019-10-14 15:44:35 -0700326 asyncResp->res.jsonValue["PCIeDevices"] = {
327 {"@odata.id",
328 "/redfish/v1/Systems/system/PCIeDevices"}};
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700329
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500330 const std::string& connectionName =
Johnathan Mantey49c53ac2019-05-02 09:22:38 -0700331 connectionNames[0].first;
James Feist1c8fba92019-12-20 15:12:07 -0800332
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500333 const std::vector<std::string>& interfaces =
James Feist1c8fba92019-12-20 15:12:07 -0800334 connectionNames[0].second;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500335 const std::array<const char*, 2> hasIndicatorLed = {
James Feist1c8fba92019-12-20 15:12:07 -0800336 "xyz.openbmc_project.Inventory.Item.Panel",
337 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
338
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500339 for (const char* interface : hasIndicatorLed)
James Feist1c8fba92019-12-20 15:12:07 -0800340 {
341 if (std::find(interfaces.begin(), interfaces.end(),
342 interface) != interfaces.end())
343 {
344 getIndicatorLedState(asyncResp);
345 break;
346 }
347 }
348
Ed Tanous1abe55e2018-09-05 08:30:59 -0700349 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700350 [asyncResp, chassisId(std::string(chassisId))](
351 const boost::system::error_code ec,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700352 const std::vector<std::pair<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500353 std::string, VariantType>>& propertiesList) {
354 for (const std::pair<std::string, VariantType>&
355 property : propertiesList)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700356 {
Shawn McCarney99cffd72019-03-01 10:46:20 -0600357 // Store DBus properties that are also Redfish
358 // properties with same name and a string value
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500359 const std::string& propertyName =
Shawn McCarney99cffd72019-03-01 10:46:20 -0600360 property.first;
361 if ((propertyName == "PartNumber") ||
362 (propertyName == "SerialNumber") ||
363 (propertyName == "Manufacturer") ||
364 (propertyName == "Model"))
Ed Tanous1abe55e2018-09-05 08:30:59 -0700365 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500366 const std::string* value =
Shawn McCarney99cffd72019-03-01 10:46:20 -0600367 std::get_if<std::string>(
368 &property.second);
369 if (value != nullptr)
370 {
371 asyncResp->res.jsonValue[propertyName] =
372 *value;
373 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700374 }
375 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700376 asyncResp->res.jsonValue["Name"] = chassisId;
377 asyncResp->res.jsonValue["Id"] = chassisId;
378 asyncResp->res.jsonValue["Thermal"] = {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700379 {"@odata.id", "/redfish/v1/Chassis/" +
380 chassisId + "/Thermal"}};
Ed Tanous2474adf2018-09-05 16:31:16 -0700381 // Power object
382 asyncResp->res.jsonValue["Power"] = {
383 {"@odata.id", "/redfish/v1/Chassis/" +
384 chassisId + "/Power"}};
Anthony Wilson95a3eca2019-06-11 10:44:47 -0500385 // SensorCollection
386 asyncResp->res.jsonValue["Sensors"] = {
387 {"@odata.id", "/redfish/v1/Chassis/" +
388 chassisId + "/Sensors"}};
Ed Tanous029573d2019-02-01 10:57:49 -0800389 asyncResp->res.jsonValue["Status"] = {
Ed Tanous029573d2019-02-01 10:57:49 -0800390 {"State", "Enabled"},
391 };
Ed Tanous2474adf2018-09-05 16:31:16 -0700392
Ed Tanous029573d2019-02-01 10:57:49 -0800393 asyncResp->res
394 .jsonValue["Links"]["ComputerSystems"] = {
395 {{"@odata.id", "/redfish/v1/Systems/system"}}};
396 asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
397 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600398 getChassisState(asyncResp);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700399 },
400 connectionName, path, "org.freedesktop.DBus.Properties",
401 "GetAll",
402 "xyz.openbmc_project.Inventory.Decorator.Asset");
Ed Tanous1abe55e2018-09-05 08:30:59 -0700403 return;
404 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700405
Ed Tanous1abe55e2018-09-05 08:30:59 -0700406 // Couldn't find an object with that name. return an error
Jason M. Billsf12894f2018-10-09 12:45:45 -0700407 messages::resourceNotFound(
Jason M. Billsadbe1922019-10-14 15:44:35 -0700408 asyncResp->res, "#Chassis.v1_10_0.Chassis", chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700409 },
410 "xyz.openbmc_project.ObjectMapper",
411 "/xyz/openbmc_project/object_mapper",
412 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
Ed Tanous271584a2019-07-09 16:24:22 -0700413 "/xyz/openbmc_project/inventory", 0, interfaces);
Qiang XUc1819422019-02-27 13:51:32 +0800414
415 getPhysicalSecurityData(asyncResp);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700416 }
James Feist1c8fba92019-12-20 15:12:07 -0800417
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500418 void doPatch(crow::Response& res, const crow::Request& req,
419 const std::vector<std::string>& params) override
James Feist1c8fba92019-12-20 15:12:07 -0800420 {
421 std::optional<std::string> indicatorLed;
422 auto asyncResp = std::make_shared<AsyncResp>(res);
423
424 if (params.size() != 1)
425 {
426 return;
427 }
428
429 if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed))
430 {
431 return;
432 }
433
434 if (!indicatorLed)
435 {
436 return; // delete this when we support more patch properties
437 }
438
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500439 const std::array<const char*, 2> interfaces = {
James Feist1c8fba92019-12-20 15:12:07 -0800440 "xyz.openbmc_project.Inventory.Item.Board",
441 "xyz.openbmc_project.Inventory.Item.Chassis"};
442
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500443 const std::string& chassisId = params[0];
James Feist1c8fba92019-12-20 15:12:07 -0800444
445 crow::connections::systemBus->async_method_call(
446 [asyncResp, chassisId, indicatorLed](
447 const boost::system::error_code ec,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500448 const crow::openbmc_mapper::GetSubTreeType& subtree) {
James Feist1c8fba92019-12-20 15:12:07 -0800449 if (ec)
450 {
451 messages::internalError(asyncResp->res);
452 return;
453 }
454
455 // Iterate over all retrieved ObjectPaths.
456 for (const std::pair<
457 std::string,
458 std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500459 std::pair<std::string, std::vector<std::string>>>>&
460 object : subtree)
James Feist1c8fba92019-12-20 15:12:07 -0800461 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500462 const std::string& path = object.first;
James Feist1c8fba92019-12-20 15:12:07 -0800463 const std::vector<
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500464 std::pair<std::string, std::vector<std::string>>>&
465 connectionNames = object.second;
James Feist1c8fba92019-12-20 15:12:07 -0800466
467 if (!boost::ends_with(path, chassisId))
468 {
469 continue;
470 }
471
472 if (connectionNames.size() < 1)
473 {
474 BMCWEB_LOG_ERROR << "Got 0 Connection names";
475 continue;
476 }
477
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500478 const std::vector<std::string>& interfaces =
James Feist1c8fba92019-12-20 15:12:07 -0800479 connectionNames[0].second;
480
481 if (indicatorLed)
482 {
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500483 const std::array<const char*, 2> hasIndicatorLed = {
James Feist1c8fba92019-12-20 15:12:07 -0800484 "xyz.openbmc_project.Inventory.Item.Panel",
485 "xyz.openbmc_project.Inventory.Item.Board."
486 "Motherboard"};
487 bool indicatorChassis = false;
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500488 for (const char* interface : hasIndicatorLed)
James Feist1c8fba92019-12-20 15:12:07 -0800489 {
490 if (std::find(interfaces.begin(), interfaces.end(),
491 interface) != interfaces.end())
492 {
493 indicatorChassis = true;
494 break;
495 }
496 }
497 if (indicatorChassis)
498 {
499 setIndicatorLedState(asyncResp,
500 std::move(*indicatorLed));
501 }
502 else
503 {
504 messages::propertyUnknown(asyncResp->res,
505 "IndicatorLED");
506 }
507 }
508 return;
509 }
510
511 messages::resourceNotFound(
512 asyncResp->res, "#Chassis.v1_10_0.Chassis", chassisId);
513 },
514 "xyz.openbmc_project.ObjectMapper",
515 "/xyz/openbmc_project/object_mapper",
516 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
517 "/xyz/openbmc_project/inventory", 0, interfaces);
518 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700519};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700520} // namespace redfish