1729dae72SJennifer Lee /* 2729dae72SJennifer Lee // Copyright (c) 2018 Intel Corporation 3729dae72SJennifer Lee // 4729dae72SJennifer Lee // Licensed under the Apache License, Version 2.0 (the "License"); 5729dae72SJennifer Lee // you may not use this file except in compliance with the License. 6729dae72SJennifer Lee // You may obtain a copy of the License at 7729dae72SJennifer Lee // 8729dae72SJennifer Lee // http://www.apache.org/licenses/LICENSE-2.0 9729dae72SJennifer Lee // 10729dae72SJennifer Lee // Unless required by applicable law or agreed to in writing, software 11729dae72SJennifer Lee // distributed under the License is distributed on an "AS IS" BASIS, 12729dae72SJennifer Lee // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13729dae72SJennifer Lee // See the License for the specific language governing permissions and 14729dae72SJennifer Lee // limitations under the License. 15729dae72SJennifer Lee */ 16729dae72SJennifer Lee #pragma once 17729dae72SJennifer Lee 18729dae72SJennifer Lee #include "node.hpp" 19729dae72SJennifer Lee #include <boost/container/flat_map.hpp> 20729dae72SJennifer Lee 21729dae72SJennifer Lee namespace redfish { 22acb7cfb4SJennifer Lee static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher; 23729dae72SJennifer Lee 24729dae72SJennifer Lee class UpdateService : public Node { 25729dae72SJennifer Lee public: 26729dae72SJennifer Lee UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/") { 27729dae72SJennifer Lee Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService"; 28729dae72SJennifer Lee Node::json["@odata.id"] = "/redfish/v1/UpdateService"; 29729dae72SJennifer Lee Node::json["@odata.context"] = 30729dae72SJennifer Lee "/redfish/v1/$metadata#UpdateService.UpdateService"; 31729dae72SJennifer Lee Node::json["Id"] = "UpdateService"; 32729dae72SJennifer Lee Node::json["Description"] = "Service for Software Update"; 33729dae72SJennifer Lee Node::json["Name"] = "Update Service"; 34acb7cfb4SJennifer Lee Node::json["HttpPushUri"] = "/redfish/v1/UpdateService"; 35*c711bf86SEd Tanous // UpdateService cannot be disabled 36*c711bf86SEd Tanous Node::json["ServiceEnabled"] = true; 376c4eb9deSJennifer Lee Node::json["FirmwareInventory"] = { 386c4eb9deSJennifer Lee {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}}; 39729dae72SJennifer Lee 40729dae72SJennifer Lee entityPrivileges = { 41729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 42729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 43729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 44729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 45729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 46729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 47729dae72SJennifer Lee } 48729dae72SJennifer Lee 49729dae72SJennifer Lee private: 5055c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 51729dae72SJennifer Lee const std::vector<std::string> ¶ms) override { 5255c7b7a2SEd Tanous res.jsonValue = Node::json; 53729dae72SJennifer Lee res.end(); 54729dae72SJennifer Lee } 55*c711bf86SEd Tanous static void activateImage(const std::string &objPath) { 56acb7cfb4SJennifer Lee crow::connections::systemBus->async_method_call( 57*c711bf86SEd Tanous [objPath](const boost::system::error_code error_code) { 58acb7cfb4SJennifer Lee if (error_code) { 59acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "error_code = " << error_code; 60acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "error msg = " << error_code.message(); 61acb7cfb4SJennifer Lee } 62acb7cfb4SJennifer Lee }, 63*c711bf86SEd Tanous "xyz.openbmc_project.Software.BMC.Updater", objPath, 64acb7cfb4SJennifer Lee "org.freedesktop.DBus.Properties", "Set", 65acb7cfb4SJennifer Lee "xyz.openbmc_project.Software.Activation", "RequestedActivation", 66acb7cfb4SJennifer Lee sdbusplus::message::variant<std::string>( 67acb7cfb4SJennifer Lee "xyz.openbmc_project.Software.Activation.RequestedActivations." 68acb7cfb4SJennifer Lee "Active")); 69acb7cfb4SJennifer Lee } 70acb7cfb4SJennifer Lee void doPost(crow::Response &res, const crow::Request &req, 71acb7cfb4SJennifer Lee const std::vector<std::string> ¶ms) override { 72acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "doPost..."; 73acb7cfb4SJennifer Lee 74acb7cfb4SJennifer Lee // Only allow one FW update at a time 75acb7cfb4SJennifer Lee if (fwUpdateMatcher != nullptr) { 76acb7cfb4SJennifer Lee res.addHeader("Retry-After", "30"); 77acb7cfb4SJennifer Lee res.result(boost::beast::http::status::service_unavailable); 78acb7cfb4SJennifer Lee res.jsonValue = messages::serviceTemporarilyUnavailable("3"); 79acb7cfb4SJennifer Lee res.end(); 80acb7cfb4SJennifer Lee return; 81acb7cfb4SJennifer Lee } 82acb7cfb4SJennifer Lee // Make this const static so it survives outside this method 83acb7cfb4SJennifer Lee static boost::asio::deadline_timer timeout(*req.ioService, 84acb7cfb4SJennifer Lee boost::posix_time::seconds(5)); 85acb7cfb4SJennifer Lee 86acb7cfb4SJennifer Lee timeout.expires_from_now(boost::posix_time::seconds(5)); 87acb7cfb4SJennifer Lee 88acb7cfb4SJennifer Lee timeout.async_wait([&res](const boost::system::error_code &ec) { 89acb7cfb4SJennifer Lee fwUpdateMatcher = nullptr; 90acb7cfb4SJennifer Lee if (ec == boost::asio::error::operation_aborted) { 91acb7cfb4SJennifer Lee // expected, we were canceled before the timer completed. 92acb7cfb4SJennifer Lee return; 93acb7cfb4SJennifer Lee } 94acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "Timed out waiting for firmware object being created"; 95acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "FW image may has already been uploaded to server"; 96acb7cfb4SJennifer Lee if (ec) { 97acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "Async_wait failed" << ec; 98acb7cfb4SJennifer Lee return; 99acb7cfb4SJennifer Lee } 100acb7cfb4SJennifer Lee 101acb7cfb4SJennifer Lee res.result(boost::beast::http::status::internal_server_error); 102acb7cfb4SJennifer Lee res.jsonValue = redfish::messages::internalError(); 103acb7cfb4SJennifer Lee res.end(); 104acb7cfb4SJennifer Lee }); 105acb7cfb4SJennifer Lee 106acb7cfb4SJennifer Lee auto callback = [&res](sdbusplus::message::message &m) { 107acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Match fired"; 108acb7cfb4SJennifer Lee bool flag = false; 109acb7cfb4SJennifer Lee 110acb7cfb4SJennifer Lee if (m.is_method_error()) { 111acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Dbus method error!!!"; 112acb7cfb4SJennifer Lee res.end(); 113acb7cfb4SJennifer Lee return; 114acb7cfb4SJennifer Lee } 115acb7cfb4SJennifer Lee std::vector<std::pair< 116acb7cfb4SJennifer Lee std::string, 117acb7cfb4SJennifer Lee std::vector<std::pair<std::string, 118acb7cfb4SJennifer Lee sdbusplus::message::variant<std::string>>>>> 119acb7cfb4SJennifer Lee interfaces_properties; 120acb7cfb4SJennifer Lee 121*c711bf86SEd Tanous sdbusplus::message::object_path objPath; 122acb7cfb4SJennifer Lee 123*c711bf86SEd Tanous m.read(objPath, interfaces_properties); // Read in the object path 124acb7cfb4SJennifer Lee // that was just created 125*c711bf86SEd Tanous // std::string str_objpath = objPath.str; // keep a copy for 126acb7cfb4SJennifer Lee // constructing response message 127*c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; // str_objpath; 128acb7cfb4SJennifer Lee for (auto &interface : interfaces_properties) { 129acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "interface = " << interface.first; 130acb7cfb4SJennifer Lee 131acb7cfb4SJennifer Lee if (interface.first == "xyz.openbmc_project.Software.Activation") { 132acb7cfb4SJennifer Lee // cancel timer only when xyz.openbmc_project.Software.Activation 133acb7cfb4SJennifer Lee // interface is added 134acb7cfb4SJennifer Lee boost::system::error_code ec; 135acb7cfb4SJennifer Lee timeout.cancel(ec); 136acb7cfb4SJennifer Lee if (ec) { 137acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "error canceling timer " << ec; 138acb7cfb4SJennifer Lee } 139*c711bf86SEd Tanous UpdateService::activateImage(objPath.str); // str_objpath); 140acb7cfb4SJennifer Lee res.jsonValue = redfish::messages::success(); 141acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "ending response"; 142acb7cfb4SJennifer Lee res.end(); 143acb7cfb4SJennifer Lee fwUpdateMatcher = nullptr; 144acb7cfb4SJennifer Lee } 145acb7cfb4SJennifer Lee } 146acb7cfb4SJennifer Lee }; 147acb7cfb4SJennifer Lee 148acb7cfb4SJennifer Lee fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>( 149acb7cfb4SJennifer Lee *crow::connections::systemBus, 150acb7cfb4SJennifer Lee "interface='org.freedesktop.DBus.ObjectManager',type='signal'," 151acb7cfb4SJennifer Lee "member='InterfacesAdded',path='/xyz/openbmc_project/software'", 152acb7cfb4SJennifer Lee callback); 153acb7cfb4SJennifer Lee 154acb7cfb4SJennifer Lee std::string filepath( 155acb7cfb4SJennifer Lee "/tmp/images/" + 156acb7cfb4SJennifer Lee boost::uuids::to_string(boost::uuids::random_generator()())); 157acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Writing file to " << filepath; 158acb7cfb4SJennifer Lee std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary | 159acb7cfb4SJennifer Lee std::ofstream::trunc); 160acb7cfb4SJennifer Lee out << req.body; 161acb7cfb4SJennifer Lee out.close(); 162acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "file upload complete!!"; 163acb7cfb4SJennifer Lee } 164729dae72SJennifer Lee }; 165729dae72SJennifer Lee 166729dae72SJennifer Lee class SoftwareInventoryCollection : public Node { 167729dae72SJennifer Lee public: 168729dae72SJennifer Lee template <typename CrowApp> 169729dae72SJennifer Lee SoftwareInventoryCollection(CrowApp &app) 1706c4eb9deSJennifer Lee : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/") { 171729dae72SJennifer Lee Node::json["@odata.type"] = 172729dae72SJennifer Lee "#SoftwareInventoryCollection.SoftwareInventoryCollection"; 1736c4eb9deSJennifer Lee Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory"; 174729dae72SJennifer Lee Node::json["@odata.context"] = 175729dae72SJennifer Lee "/redfish/v1/" 176729dae72SJennifer Lee "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection"; 177729dae72SJennifer Lee Node::json["Name"] = "Software Inventory Collection"; 178729dae72SJennifer Lee 179729dae72SJennifer Lee entityPrivileges = { 180729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 181729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 182729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 183729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 184729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 185729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 186729dae72SJennifer Lee } 187729dae72SJennifer Lee 188729dae72SJennifer Lee private: 18955c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 190729dae72SJennifer Lee const std::vector<std::string> ¶ms) override { 191*c711bf86SEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 19255c7b7a2SEd Tanous res.jsonValue = Node::json; 193*c711bf86SEd Tanous 194*c711bf86SEd Tanous crow::connections::systemBus->async_method_call( 195*c711bf86SEd Tanous [asyncResp]( 196*c711bf86SEd Tanous const boost::system::error_code ec, 1976c4eb9deSJennifer Lee const std::vector<std::pair< 1986c4eb9deSJennifer Lee std::string, 1996c4eb9deSJennifer Lee std::vector<std::pair<std::string, std::vector<std::string>>>>> 2006c4eb9deSJennifer Lee &subtree) { 201*c711bf86SEd Tanous if (ec) { 202*c711bf86SEd Tanous asyncResp->res.result( 203*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 2046c4eb9deSJennifer Lee return; 205729dae72SJennifer Lee } 206*c711bf86SEd Tanous asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); 207*c711bf86SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 2086c4eb9deSJennifer Lee 2096c4eb9deSJennifer Lee for (auto &obj : subtree) { 2106c4eb9deSJennifer Lee const std::vector<std::pair<std::string, std::vector<std::string>>> 2116c4eb9deSJennifer Lee &connections = obj.second; 2126c4eb9deSJennifer Lee 213*c711bf86SEd Tanous for (auto &conn : connections) { 214*c711bf86SEd Tanous const std::string &connectionName = conn.first; 21555c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "connectionName = " << connectionName; 21655c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "obj.first = " << obj.first; 2176c4eb9deSJennifer Lee 21855c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 219*c711bf86SEd Tanous [asyncResp](const boost::system::error_code error_code, 220*c711bf86SEd Tanous const VariantType &activation) { 22155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "safe returned in lambda function"; 2226c4eb9deSJennifer Lee if (error_code) { 223acb7cfb4SJennifer Lee asyncResp->res.result( 2246c4eb9deSJennifer Lee boost::beast::http::status::internal_server_error); 2256c4eb9deSJennifer Lee return; 2266c4eb9deSJennifer Lee } 227*c711bf86SEd Tanous 228*c711bf86SEd Tanous const std::string *sw_inv_purpose = 229*c711bf86SEd Tanous mapbox::getPtr<const std::string>(activation); 230*c711bf86SEd Tanous if (sw_inv_purpose == nullptr) { 231*c711bf86SEd Tanous asyncResp->res.result( 232*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 233acb7cfb4SJennifer Lee return; 234acb7cfb4SJennifer Lee } 235*c711bf86SEd Tanous std::size_t last_pos = sw_inv_purpose->rfind("."); 236*c711bf86SEd Tanous if (last_pos == std::string::npos) { 237*c711bf86SEd Tanous asyncResp->res.result( 238*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 239*c711bf86SEd Tanous return; 240*c711bf86SEd Tanous } 241*c711bf86SEd Tanous nlohmann::json &members = 242*c711bf86SEd Tanous asyncResp->res.jsonValue["Members"]; 243*c711bf86SEd Tanous members.push_back( 2446c4eb9deSJennifer Lee {{"@odata.id", 2456c4eb9deSJennifer Lee "/redfish/v1/UpdateService/FirmwareInventory/" + 246*c711bf86SEd Tanous sw_inv_purpose->substr(last_pos + 1)}}); 247acb7cfb4SJennifer Lee asyncResp->res.jsonValue["Members@odata.count"] = 248*c711bf86SEd Tanous members.size(); 2496c4eb9deSJennifer Lee }, 2506c4eb9deSJennifer Lee connectionName, obj.first, "org.freedesktop.DBus.Properties", 251acb7cfb4SJennifer Lee "Get", "xyz.openbmc_project.Software.Activation", 252acb7cfb4SJennifer Lee "Activation"); 2536c4eb9deSJennifer Lee } 2546c4eb9deSJennifer Lee } 255*c711bf86SEd Tanous }, 256*c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", 257*c711bf86SEd Tanous "/xyz/openbmc_project/object_mapper", 258*c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 259*c711bf86SEd Tanous "/xyz/openbmc_project/software", int32_t(1), 260*c711bf86SEd Tanous std::array<const char *, 1>{"xyz.openbmc_project.Software.Version"}); 261729dae72SJennifer Lee } 262729dae72SJennifer Lee }; 263*c711bf86SEd Tanous 264729dae72SJennifer Lee class SoftwareInventory : public Node { 265729dae72SJennifer Lee public: 266729dae72SJennifer Lee template <typename CrowApp> 267729dae72SJennifer Lee SoftwareInventory(CrowApp &app) 2686c4eb9deSJennifer Lee : Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/", 269729dae72SJennifer Lee std::string()) { 270729dae72SJennifer Lee Node::json["@odata.type"] = "#SoftwareInventory.v1_1_0.SoftwareInventory"; 271729dae72SJennifer Lee Node::json["@odata.context"] = 272729dae72SJennifer Lee "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory"; 273729dae72SJennifer Lee Node::json["Name"] = "Software Inventory"; 2746c4eb9deSJennifer Lee Node::json["Updateable"] = false; 275acb7cfb4SJennifer Lee Node::json["Status"]["Health"] = "OK"; 276acb7cfb4SJennifer Lee Node::json["Status"]["HealthRollup"] = "OK"; 277acb7cfb4SJennifer Lee Node::json["Status"]["State"] = "Enabled"; 278729dae72SJennifer Lee entityPrivileges = { 279729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 280729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 281729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 282729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 283729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 284729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 285729dae72SJennifer Lee } 286729dae72SJennifer Lee 287729dae72SJennifer Lee private: 28855c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 289729dae72SJennifer Lee const std::vector<std::string> ¶ms) override { 290*c711bf86SEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 29155c7b7a2SEd Tanous res.jsonValue = Node::json; 2926c4eb9deSJennifer Lee 293729dae72SJennifer Lee if (params.size() != 1) { 294729dae72SJennifer Lee res.result(boost::beast::http::status::internal_server_error); 295acb7cfb4SJennifer Lee res.jsonValue = messages::internalError(); 296729dae72SJennifer Lee res.end(); 297729dae72SJennifer Lee return; 298729dae72SJennifer Lee } 299729dae72SJennifer Lee 300*c711bf86SEd Tanous std::shared_ptr<std::string> sw_id = 301*c711bf86SEd Tanous std::make_shared<std::string>(params[0]); 302*c711bf86SEd Tanous 30355c7b7a2SEd Tanous res.jsonValue["@odata.id"] = 304*c711bf86SEd Tanous "/redfish/v1/UpdateService/FirmwareInventory/" + *sw_id; 305*c711bf86SEd Tanous 306*c711bf86SEd Tanous crow::connections::systemBus->async_method_call( 307*c711bf86SEd Tanous [asyncResp, sw_id]( 308*c711bf86SEd Tanous const boost::system::error_code ec, 3096c4eb9deSJennifer Lee const std::vector<std::pair< 3106c4eb9deSJennifer Lee std::string, 3116c4eb9deSJennifer Lee std::vector<std::pair<std::string, std::vector<std::string>>>>> 3126c4eb9deSJennifer Lee &subtree) { 31355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "doGet callback..."; 314*c711bf86SEd Tanous if (ec) { 315*c711bf86SEd Tanous asyncResp->res.result( 316*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 3176c4eb9deSJennifer Lee return; 3186c4eb9deSJennifer Lee } 3196c4eb9deSJennifer Lee 320*c711bf86SEd Tanous for (const std::pair<std::string, 321*c711bf86SEd Tanous std::vector<std::pair<std::string, 322*c711bf86SEd Tanous std::vector<std::string>>>> 323*c711bf86SEd Tanous &obj : subtree) { 324*c711bf86SEd Tanous if (boost::ends_with(obj.first, *sw_id) != true) { 325acb7cfb4SJennifer Lee continue; 326acb7cfb4SJennifer Lee } 327acb7cfb4SJennifer Lee 328*c711bf86SEd Tanous if (obj.second.size() <= 1) { 329acb7cfb4SJennifer Lee continue; 330acb7cfb4SJennifer Lee } 3316c4eb9deSJennifer Lee 33255c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 333*c711bf86SEd Tanous [asyncResp, sw_id]( 3346c4eb9deSJennifer Lee const boost::system::error_code error_code, 3356c4eb9deSJennifer Lee const boost::container::flat_map<std::string, VariantType> 3366c4eb9deSJennifer Lee &propertiesList) { 3376c4eb9deSJennifer Lee if (error_code) { 338*c711bf86SEd Tanous asyncResp->res.result( 339*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 3406c4eb9deSJennifer Lee return; 3416c4eb9deSJennifer Lee } 3426c4eb9deSJennifer Lee boost::container::flat_map<std::string, 3436c4eb9deSJennifer Lee VariantType>::const_iterator it = 3446c4eb9deSJennifer Lee propertiesList.find("Purpose"); 3456c4eb9deSJennifer Lee if (it == propertiesList.end()) { 346*c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "Can't find property \"Purpose\"!"; 347*c711bf86SEd Tanous asyncResp->res.result( 348*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 3496c4eb9deSJennifer Lee return; 3506c4eb9deSJennifer Lee } 351acb7cfb4SJennifer Lee const std::string *sw_inv_purpose = 352acb7cfb4SJennifer Lee mapbox::getPtr<const std::string>(it->second); 353acb7cfb4SJennifer Lee if (sw_inv_purpose == nullptr) { 354*c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "wrong types for property\"Purpose\"!"; 355*c711bf86SEd Tanous asyncResp->res.result( 356*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 357acb7cfb4SJennifer Lee return; 358acb7cfb4SJennifer Lee } 359*c711bf86SEd Tanous 360*c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "sw_inv_purpose = " << *sw_inv_purpose; 361*c711bf86SEd Tanous if (boost::ends_with(*sw_inv_purpose, "." + *sw_id)) { 362*c711bf86SEd Tanous it = propertiesList.find("Version"); 363*c711bf86SEd Tanous if (it == propertiesList.end()) { 364*c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "Can't find property \"Version\"!"; 365*c711bf86SEd Tanous asyncResp->res.result( 366*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 367*c711bf86SEd Tanous return; 368acb7cfb4SJennifer Lee } 369acb7cfb4SJennifer Lee 370acb7cfb4SJennifer Lee const std::string *version = 371acb7cfb4SJennifer Lee mapbox::getPtr<const std::string>(it->second); 372*c711bf86SEd Tanous 373*c711bf86SEd Tanous if (version != nullptr) { 374*c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "Can't find property \"Version\"!"; 375*c711bf86SEd Tanous asyncResp->res.result( 376*c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 3776c4eb9deSJennifer Lee return; 3786c4eb9deSJennifer Lee } 379*c711bf86SEd Tanous asyncResp->res.jsonValue["Version"] = *version; 380*c711bf86SEd Tanous asyncResp->res.jsonValue["Id"] = *sw_id; 3816c4eb9deSJennifer Lee } 3826c4eb9deSJennifer Lee }, 383*c711bf86SEd Tanous obj.second[0].first, obj.first, 384*c711bf86SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 385*c711bf86SEd Tanous "xyz.openbmc_project.Software.Version"); 3866c4eb9deSJennifer Lee } 387*c711bf86SEd Tanous }, 388*c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", 389*c711bf86SEd Tanous "/xyz/openbmc_project/object_mapper", 390*c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 391*c711bf86SEd Tanous "/xyz/openbmc_project/software", int32_t(1), 392*c711bf86SEd Tanous std::array<const char *, 1>{"xyz.openbmc_project.Software.Version"}); 3936c4eb9deSJennifer Lee } 394729dae72SJennifer Lee }; 395729dae72SJennifer Lee 396729dae72SJennifer Lee } // namespace redfish 397