blob: efa0fbfbf8c5717715f35279c39b694ddad7ebb7 [file] [log] [blame]
Jennifer Lee729dae72018-04-24 15:59:34 -07001/*
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
18#include "node.hpp"
19#include <boost/container/flat_map.hpp>
20
21namespace redfish {
Jennifer Leeacb7cfb2018-06-07 16:08:15 -070022static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher;
Jennifer Lee729dae72018-04-24 15:59:34 -070023
24class OnDemandSoftwareInventoryProvider {
25 public:
26 template <typename CallbackFunc>
Jennifer Leeacb7cfb2018-06-07 16:08:15 -070027 void getAllSoftwareInventoryObject(CallbackFunc &&callback) {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070028 crow::connections::systemBus->async_method_call(
Jennifer Lee729dae72018-04-24 15:59:34 -070029 [callback{std::move(callback)}](
30 const boost::system::error_code error_code,
31 const std::vector<std::pair<
32 std::string,
33 std::vector<std::pair<std::string, std::vector<std::string>>>>>
34 &subtree) {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070035 BMCWEB_LOG_DEBUG << "get all software inventory object callback...";
Jennifer Lee729dae72018-04-24 15:59:34 -070036 if (error_code) {
37 // Something wrong on DBus, the error_code is not important at this
38 // moment, just return success=false, and empty output. Since size
39 // of vector may vary depending on information from Entity Manager,
40 // and empty output could not be treated same way as error.
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -070041 callback(false, subtree);
Jennifer Lee729dae72018-04-24 15:59:34 -070042 return;
43 }
44
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -070045 if (subtree.empty()) {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070046 BMCWEB_LOG_DEBUG << "subtree empty";
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -070047 callback(false, subtree);
48 } else {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070049 BMCWEB_LOG_DEBUG << "subtree has something";
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -070050 callback(true, subtree);
Jennifer Lee729dae72018-04-24 15:59:34 -070051 }
52 },
53 "xyz.openbmc_project.ObjectMapper",
54 "/xyz/openbmc_project/object_mapper",
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -070055 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
56 "/xyz/openbmc_project/software", int32_t(1),
Jennifer Leeacb7cfb2018-06-07 16:08:15 -070057 std::array<const char *, 1>{"xyz.openbmc_project.Software.Activation"});
Jennifer Lee729dae72018-04-24 15:59:34 -070058 }
Jennifer Lee729dae72018-04-24 15:59:34 -070059};
60
61class UpdateService : public Node {
62 public:
63 UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/") {
64 Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService";
65 Node::json["@odata.id"] = "/redfish/v1/UpdateService";
66 Node::json["@odata.context"] =
67 "/redfish/v1/$metadata#UpdateService.UpdateService";
68 Node::json["Id"] = "UpdateService";
69 Node::json["Description"] = "Service for Software Update";
70 Node::json["Name"] = "Update Service";
Jennifer Leeacb7cfb2018-06-07 16:08:15 -070071 Node::json["HttpPushUri"] = "/redfish/v1/UpdateService";
Jennifer Lee729dae72018-04-24 15:59:34 -070072 Node::json["ServiceEnabled"] = true; // UpdateService cannot be disabled
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -070073 Node::json["FirmwareInventory"] = {
74 {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}};
Jennifer Lee729dae72018-04-24 15:59:34 -070075
76 entityPrivileges = {
77 {boost::beast::http::verb::get, {{"Login"}}},
78 {boost::beast::http::verb::head, {{"Login"}}},
79 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
80 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
81 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
82 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
83 }
84
85 private:
Ed Tanous55c7b7a2018-05-22 15:27:24 -070086 void doGet(crow::Response &res, const crow::Request &req,
Jennifer Lee729dae72018-04-24 15:59:34 -070087 const std::vector<std::string> &params) override {
Ed Tanous55c7b7a2018-05-22 15:27:24 -070088 res.jsonValue = Node::json;
Jennifer Lee729dae72018-04-24 15:59:34 -070089 res.end();
90 }
Jennifer Leeacb7cfb2018-06-07 16:08:15 -070091 static void activateImage(const std::string &obj_path) {
92 crow::connections::systemBus->async_method_call(
93 [obj_path](const boost::system::error_code error_code) {
94 if (error_code) {
95 BMCWEB_LOG_DEBUG << "error_code = " << error_code;
96 BMCWEB_LOG_DEBUG << "error msg = " << error_code.message();
97 }
98 },
99 "xyz.openbmc_project.Software.BMC.Updater", obj_path,
100 "org.freedesktop.DBus.Properties", "Set",
101 "xyz.openbmc_project.Software.Activation", "RequestedActivation",
102 sdbusplus::message::variant<std::string>(
103 "xyz.openbmc_project.Software.Activation.RequestedActivations."
104 "Active"));
105 }
106 void doPost(crow::Response &res, const crow::Request &req,
107 const std::vector<std::string> &params) override {
108 BMCWEB_LOG_DEBUG << "doPost...";
109
110 // Only allow one FW update at a time
111 if (fwUpdateMatcher != nullptr) {
112 res.addHeader("Retry-After", "30");
113 res.result(boost::beast::http::status::service_unavailable);
114 res.jsonValue = messages::serviceTemporarilyUnavailable("3");
115 res.end();
116 return;
117 }
118 // Make this const static so it survives outside this method
119 static boost::asio::deadline_timer timeout(*req.ioService,
120 boost::posix_time::seconds(5));
121
122 timeout.expires_from_now(boost::posix_time::seconds(5));
123
124 timeout.async_wait([&res](const boost::system::error_code &ec) {
125 fwUpdateMatcher = nullptr;
126 if (ec == boost::asio::error::operation_aborted) {
127 // expected, we were canceled before the timer completed.
128 return;
129 }
130 BMCWEB_LOG_ERROR << "Timed out waiting for firmware object being created";
131 BMCWEB_LOG_ERROR << "FW image may has already been uploaded to server";
132 if (ec) {
133 BMCWEB_LOG_ERROR << "Async_wait failed" << ec;
134 return;
135 }
136
137 res.result(boost::beast::http::status::internal_server_error);
138 res.jsonValue = redfish::messages::internalError();
139 res.end();
140 });
141
142 auto callback = [&res](sdbusplus::message::message &m) {
143 BMCWEB_LOG_DEBUG << "Match fired";
144 bool flag = false;
145
146 if (m.is_method_error()) {
147 BMCWEB_LOG_DEBUG << "Dbus method error!!!";
148 res.end();
149 return;
150 }
151 std::vector<std::pair<
152 std::string,
153 std::vector<std::pair<std::string,
154 sdbusplus::message::variant<std::string>>>>>
155 interfaces_properties;
156
157 sdbusplus::message::object_path obj_path;
158
159 m.read(obj_path, interfaces_properties); // Read in the object path
160 // that was just created
161 // std::string str_objpath = obj_path.str; // keep a copy for
162 // constructing response message
163 BMCWEB_LOG_DEBUG << "obj path = " << obj_path.str; // str_objpath;
164 for (auto &interface : interfaces_properties) {
165 BMCWEB_LOG_DEBUG << "interface = " << interface.first;
166
167 if (interface.first == "xyz.openbmc_project.Software.Activation") {
168 // cancel timer only when xyz.openbmc_project.Software.Activation
169 // interface is added
170 boost::system::error_code ec;
171 timeout.cancel(ec);
172 if (ec) {
173 BMCWEB_LOG_ERROR << "error canceling timer " << ec;
174 }
175 UpdateService::activateImage(obj_path.str); // str_objpath);
176 res.jsonValue = redfish::messages::success();
177 BMCWEB_LOG_DEBUG << "ending response";
178 res.end();
179 fwUpdateMatcher = nullptr;
180 }
181 }
182 };
183
184 fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>(
185 *crow::connections::systemBus,
186 "interface='org.freedesktop.DBus.ObjectManager',type='signal',"
187 "member='InterfacesAdded',path='/xyz/openbmc_project/software'",
188 callback);
189
190 std::string filepath(
191 "/tmp/images/" +
192 boost::uuids::to_string(boost::uuids::random_generator()()));
193 BMCWEB_LOG_DEBUG << "Writing file to " << filepath;
194 std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary |
195 std::ofstream::trunc);
196 out << req.body;
197 out.close();
198 BMCWEB_LOG_DEBUG << "file upload complete!!";
199 }
Jennifer Lee729dae72018-04-24 15:59:34 -0700200};
201
202class SoftwareInventoryCollection : public Node {
203 public:
204 /*
205 * Default Constructor
206 */
207 template <typename CrowApp>
208 SoftwareInventoryCollection(CrowApp &app)
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700209 : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/") {
Jennifer Lee729dae72018-04-24 15:59:34 -0700210 Node::json["@odata.type"] =
211 "#SoftwareInventoryCollection.SoftwareInventoryCollection";
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700212 Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory";
Jennifer Lee729dae72018-04-24 15:59:34 -0700213 Node::json["@odata.context"] =
214 "/redfish/v1/"
215 "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection";
216 Node::json["Name"] = "Software Inventory Collection";
217
218 entityPrivileges = {
219 {boost::beast::http::verb::get, {{"Login"}}},
220 {boost::beast::http::verb::head, {{"Login"}}},
221 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
222 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
223 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
224 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
225 }
226
227 private:
228 /**
229 * Functions triggers appropriate requests on DBus
230 */
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700231 void doGet(crow::Response &res, const crow::Request &req,
Jennifer Lee729dae72018-04-24 15:59:34 -0700232 const std::vector<std::string> &params) override {
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700233 res.jsonValue = Node::json;
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700234 softwareInventoryProvider.getAllSoftwareInventoryObject(
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700235 [&](const bool &success,
236 const std::vector<std::pair<
237 std::string,
238 std::vector<std::pair<std::string, std::vector<std::string>>>>>
239 &subtree) {
240 if (!success) {
Jennifer Lee729dae72018-04-24 15:59:34 -0700241 res.result(boost::beast::http::status::internal_server_error);
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700242 res.jsonValue = messages::internalError();
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700243 res.end();
244 return;
Jennifer Lee729dae72018-04-24 15:59:34 -0700245 }
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700246
247 if (subtree.empty()) {
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700248 BMCWEB_LOG_DEBUG << "subtree empty!!";
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700249 res.result(boost::beast::http::status::internal_server_error);
250 res.jsonValue = messages::internalError();
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700251 res.end();
252 return;
253 }
254
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700255 res.jsonValue["Members"] = nlohmann::json::array();
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700256 res.jsonValue["Members@odata.count"] = 0;
257
258 std::shared_ptr<AsyncResp> asyncResp =
259 std::make_shared<AsyncResp>(res);
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700260
261 for (auto &obj : subtree) {
262 const std::vector<std::pair<std::string, std::vector<std::string>>>
263 &connections = obj.second;
264
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700265 // if can't parse fw id then return
266 std::size_t id_pos;
267 if ((id_pos = obj.first.rfind("/")) == std::string::npos) {
268 res.result(boost::beast::http::status::internal_server_error);
269 res.jsonValue = messages::internalError();
270 BMCWEB_LOG_DEBUG << "Can't parse firmware ID!!";
271 res.end();
272 return;
273 }
274 std::string fw_id = obj.first.substr(id_pos + 1);
275
276 for (const auto &conn : connections) {
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700277 const std::string connectionName = conn.first;
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700278 BMCWEB_LOG_DEBUG << "connectionName = " << connectionName;
279 BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700280
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700281 crow::connections::systemBus->async_method_call(
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700282 [asyncResp, fw_id](
283 const boost::system::error_code error_code,
284 const sdbusplus::message::variant<std::string>
285 &activation_status) {
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700286 BMCWEB_LOG_DEBUG << "safe returned in lambda function";
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700287 if (error_code) {
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700288 asyncResp->res.result(
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700289 boost::beast::http::status::internal_server_error);
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700290 asyncResp->res.jsonValue = messages::internalError();
291 asyncResp->res.end();
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700292 return;
293 }
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700294 const std::string *activation_status_str =
295 mapbox::getPtr<const std::string>(activation_status);
296 if (activation_status_str != nullptr &&
297 *activation_status_str !=
298 "xyz.openbmc_project.Software.Activation."
299 "Activations.Active") {
300 // The activation status of this software is not currently
301 // active, so does not need to be listed in the response
302 return;
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700303 }
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700304 asyncResp->res.jsonValue["Members"].push_back(
305 {{"@odata.id",
306 "/redfish/v1/UpdateService/FirmwareInventory/" +
307 fw_id}});
308 asyncResp->res.jsonValue["Members@odata.count"] =
309 asyncResp->res.jsonValue["Members"].size();
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700310 },
311 connectionName, obj.first, "org.freedesktop.DBus.Properties",
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700312 "Get", "xyz.openbmc_project.Software.Activation",
313 "Activation");
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700314 }
315 }
Jennifer Lee729dae72018-04-24 15:59:34 -0700316 });
Jennifer Lee729dae72018-04-24 15:59:34 -0700317 }
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700318
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700319 OnDemandSoftwareInventoryProvider softwareInventoryProvider;
Jennifer Lee729dae72018-04-24 15:59:34 -0700320};
321/**
322 * Chassis override class for delivering Chassis Schema
323 */
324class SoftwareInventory : public Node {
325 public:
326 /*
327 * Default Constructor
328 */
329 template <typename CrowApp>
330 SoftwareInventory(CrowApp &app)
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700331 : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/",
Jennifer Lee729dae72018-04-24 15:59:34 -0700332 std::string()) {
333 Node::json["@odata.type"] = "#SoftwareInventory.v1_1_0.SoftwareInventory";
Jennifer Lee729dae72018-04-24 15:59:34 -0700334 Node::json["@odata.context"] =
335 "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory";
336 Node::json["Name"] = "Software Inventory";
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700337 Node::json["Updateable"] = false;
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700338 Node::json["Status"]["Health"] = "OK";
339 Node::json["Status"]["HealthRollup"] = "OK";
340 Node::json["Status"]["State"] = "Enabled";
Jennifer Lee729dae72018-04-24 15:59:34 -0700341 entityPrivileges = {
342 {boost::beast::http::verb::get, {{"Login"}}},
343 {boost::beast::http::verb::head, {{"Login"}}},
344 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
345 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
346 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
347 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
348 }
349
350 private:
351 /**
352 * Functions triggers appropriate requests on DBus
353 */
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700354 void doGet(crow::Response &res, const crow::Request &req,
Jennifer Lee729dae72018-04-24 15:59:34 -0700355 const std::vector<std::string> &params) override {
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700356 res.jsonValue = Node::json;
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700357
Jennifer Lee729dae72018-04-24 15:59:34 -0700358 if (params.size() != 1) {
359 res.result(boost::beast::http::status::internal_server_error);
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700360 res.jsonValue = messages::internalError();
Jennifer Lee729dae72018-04-24 15:59:34 -0700361 res.end();
362 return;
363 }
Jennifer Lee729dae72018-04-24 15:59:34 -0700364
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700365 const std::string &fw_id = params[0];
366 res.jsonValue["Id"] = fw_id;
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700367 res.jsonValue["@odata.id"] =
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700368 "/redfish/v1/UpdateService/FirmwareInventory/" + fw_id;
369 softwareInventoryProvider.getAllSoftwareInventoryObject([
370 &res, id{std::string(fw_id)}
371 ](const bool &success,
372 const std::vector<std::pair<
373 std::string,
374 std::vector<std::pair<std::string, std::vector<std::string>>>>>
375 &subtree) {
376 BMCWEB_LOG_DEBUG << "doGet callback...";
377 if (!success) {
378 res.result(boost::beast::http::status::internal_server_error);
379 res.jsonValue = messages::internalError();
380 res.end();
381 return;
382 }
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700383
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700384 if (subtree.empty()) {
385 BMCWEB_LOG_ERROR << "subtree empty!!";
386 res.result(boost::beast::http::status::not_found);
387 res.end();
388 return;
389 }
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700390
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700391 bool fw_id_found = false;
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700392
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700393 for (auto &obj : subtree) {
394 if (boost::ends_with(obj.first, id) != true) {
395 continue;
396 }
397 fw_id_found = true;
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700398
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700399 const std::vector<std::pair<std::string, std::vector<std::string>>>
400 &connections = obj.second;
Jennifer Lee6c4eb9d2018-05-22 10:58:31 -0700401
Jennifer Leeacb7cfb2018-06-07 16:08:15 -0700402 if (connections.size() <= 0) {
403 continue;
404 }
405 const std::pair<std::string, std::vector<std::string>> &conn =
406 connections[0];
407 const std::string &connectionName = conn.first;
408 BMCWEB_LOG_DEBUG << "connectionName = " << connectionName;
409 BMCWEB_LOG_DEBUG << "obj.first = " << obj.first;
410
411 crow::connections::systemBus->async_method_call(
412 [&res, id](
413 const boost::system::error_code error_code,
414 const boost::container::flat_map<std::string, VariantType>
415 &propertiesList) {
416 if (error_code) {
417 res.result(boost::beast::http::status::internal_server_error);
418 res.jsonValue = messages::internalError();
419 res.end();
420 return;
421 }
422
423 boost::container::flat_map<std::string,
424 VariantType>::const_iterator it =
425 propertiesList.find("Purpose");
426 if (it == propertiesList.end()) {
427 BMCWEB_LOG_ERROR << "Can't find property \"Purpose\"!";
428 res.result(boost::beast::http::status::internal_server_error);
429 res.jsonValue = messages::internalError();
430 res.end();
431 return;
432 }
433
434 // SoftwareId
435 const std::string *sw_inv_purpose =
436 mapbox::getPtr<const std::string>(it->second);
437 if (sw_inv_purpose == nullptr) {
438 res.jsonValue = redfish::messages::internalError();
439 res.jsonValue = messages::internalError();
440 return;
441 }
442 BMCWEB_LOG_DEBUG << "sw_inv_purpose = " << sw_inv_purpose;
443 std::size_t last_pos = sw_inv_purpose->rfind(".");
444 if (last_pos != std::string::npos) {
445 res.jsonValue["SoftwareId"] =
446 sw_inv_purpose->substr(last_pos + 1);
447 } else {
448 BMCWEB_LOG_ERROR << "Can't parse software purpose!";
449 }
450
451 // Version
452 it = propertiesList.find("Version");
453 if (it != propertiesList.end()) {
454 const std::string *version =
455 mapbox::getPtr<const std::string>(it->second);
456 if (version == nullptr) {
457 res.jsonValue = redfish::messages::internalError();
458 res.jsonValue = messages::internalError();
459 return;
460 }
461 res.jsonValue["Version"] =
462 *(mapbox::getPtr<const std::string>(it->second));
463 } else {
464 BMCWEB_LOG_DEBUG << "Can't find version info!";
465 }
466
467 res.end();
468 },
469 connectionName, obj.first, "org.freedesktop.DBus.Properties",
470 "GetAll", "xyz.openbmc_project.Software.Version");
471 }
472 if (!fw_id_found) {
473 res.result(boost::beast::http::status::not_found);
474 res.end();
475 return;
476 }
477 });
Jennifer Lee729dae72018-04-24 15:59:34 -0700478 }
479
Ed Tanous55c7b7a2018-05-22 15:27:24 -0700480 OnDemandSoftwareInventoryProvider softwareInventoryProvider;
Jennifer Lee729dae72018-04-24 15:59:34 -0700481};
482
483} // namespace redfish