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" 191abe55efSEd Tanous 20729dae72SJennifer Lee #include <boost/container/flat_map.hpp> 21729dae72SJennifer Lee 221abe55efSEd Tanous namespace redfish 231abe55efSEd Tanous { 24*27826b5fSEd Tanous 25acb7cfb4SJennifer Lee static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher; 26729dae72SJennifer Lee 271abe55efSEd Tanous class UpdateService : public Node 281abe55efSEd Tanous { 29729dae72SJennifer Lee public: 301abe55efSEd Tanous UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/") 311abe55efSEd Tanous { 32729dae72SJennifer Lee Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService"; 33729dae72SJennifer Lee Node::json["@odata.id"] = "/redfish/v1/UpdateService"; 34729dae72SJennifer Lee Node::json["@odata.context"] = 35729dae72SJennifer Lee "/redfish/v1/$metadata#UpdateService.UpdateService"; 36729dae72SJennifer Lee Node::json["Id"] = "UpdateService"; 37729dae72SJennifer Lee Node::json["Description"] = "Service for Software Update"; 38729dae72SJennifer Lee Node::json["Name"] = "Update Service"; 39acb7cfb4SJennifer Lee Node::json["HttpPushUri"] = "/redfish/v1/UpdateService"; 40c711bf86SEd Tanous // UpdateService cannot be disabled 41c711bf86SEd Tanous Node::json["ServiceEnabled"] = true; 426c4eb9deSJennifer Lee Node::json["FirmwareInventory"] = { 436c4eb9deSJennifer Lee {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}}; 44729dae72SJennifer Lee 45729dae72SJennifer Lee entityPrivileges = { 46729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 47729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 48729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 49729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 50729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 51729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 52729dae72SJennifer Lee } 53729dae72SJennifer Lee 54729dae72SJennifer Lee private: 5555c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 561abe55efSEd Tanous const std::vector<std::string> ¶ms) override 571abe55efSEd Tanous { 5855c7b7a2SEd Tanous res.jsonValue = Node::json; 59729dae72SJennifer Lee res.end(); 60729dae72SJennifer Lee } 611abe55efSEd Tanous static void activateImage(const std::string &objPath) 621abe55efSEd Tanous { 63acb7cfb4SJennifer Lee crow::connections::systemBus->async_method_call( 64c711bf86SEd Tanous [objPath](const boost::system::error_code error_code) { 651abe55efSEd Tanous if (error_code) 661abe55efSEd Tanous { 67acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "error_code = " << error_code; 68acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "error msg = " << error_code.message(); 69acb7cfb4SJennifer Lee } 70acb7cfb4SJennifer Lee }, 71c711bf86SEd Tanous "xyz.openbmc_project.Software.BMC.Updater", objPath, 72acb7cfb4SJennifer Lee "org.freedesktop.DBus.Properties", "Set", 73acb7cfb4SJennifer Lee "xyz.openbmc_project.Software.Activation", "RequestedActivation", 74acb7cfb4SJennifer Lee sdbusplus::message::variant<std::string>( 75acb7cfb4SJennifer Lee "xyz.openbmc_project.Software.Activation.RequestedActivations." 76acb7cfb4SJennifer Lee "Active")); 77acb7cfb4SJennifer Lee } 78acb7cfb4SJennifer Lee void doPost(crow::Response &res, const crow::Request &req, 791abe55efSEd Tanous const std::vector<std::string> ¶ms) override 801abe55efSEd Tanous { 81acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "doPost..."; 82acb7cfb4SJennifer Lee 83acb7cfb4SJennifer Lee // Only allow one FW update at a time 841abe55efSEd Tanous if (fwUpdateMatcher != nullptr) 851abe55efSEd Tanous { 86acb7cfb4SJennifer Lee res.addHeader("Retry-After", "30"); 87f12894f8SJason M. Bills messages::serviceTemporarilyUnavailable(res, "3"); 88acb7cfb4SJennifer Lee res.end(); 89acb7cfb4SJennifer Lee return; 90acb7cfb4SJennifer Lee } 91acb7cfb4SJennifer Lee // Make this const static so it survives outside this method 921abe55efSEd Tanous static boost::asio::deadline_timer timeout( 931abe55efSEd Tanous *req.ioService, boost::posix_time::seconds(5)); 94acb7cfb4SJennifer Lee 95acb7cfb4SJennifer Lee timeout.expires_from_now(boost::posix_time::seconds(5)); 96acb7cfb4SJennifer Lee 97acb7cfb4SJennifer Lee timeout.async_wait([&res](const boost::system::error_code &ec) { 98acb7cfb4SJennifer Lee fwUpdateMatcher = nullptr; 991abe55efSEd Tanous if (ec == boost::asio::error::operation_aborted) 1001abe55efSEd Tanous { 101acb7cfb4SJennifer Lee // expected, we were canceled before the timer completed. 102acb7cfb4SJennifer Lee return; 103acb7cfb4SJennifer Lee } 1041abe55efSEd Tanous BMCWEB_LOG_ERROR 1051abe55efSEd Tanous << "Timed out waiting for firmware object being created"; 1061abe55efSEd Tanous BMCWEB_LOG_ERROR 1071abe55efSEd Tanous << "FW image may has already been uploaded to server"; 1081abe55efSEd Tanous if (ec) 1091abe55efSEd Tanous { 110acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "Async_wait failed" << ec; 111acb7cfb4SJennifer Lee return; 112acb7cfb4SJennifer Lee } 113acb7cfb4SJennifer Lee 114f12894f8SJason M. Bills redfish::messages::internalError(res); 115acb7cfb4SJennifer Lee res.end(); 116acb7cfb4SJennifer Lee }); 117acb7cfb4SJennifer Lee 118acb7cfb4SJennifer Lee auto callback = [&res](sdbusplus::message::message &m) { 119acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Match fired"; 120acb7cfb4SJennifer Lee bool flag = false; 121acb7cfb4SJennifer Lee 1221abe55efSEd Tanous if (m.is_method_error()) 1231abe55efSEd Tanous { 124acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Dbus method error!!!"; 125acb7cfb4SJennifer Lee res.end(); 126acb7cfb4SJennifer Lee return; 127acb7cfb4SJennifer Lee } 128acb7cfb4SJennifer Lee std::vector<std::pair< 129acb7cfb4SJennifer Lee std::string, 1301abe55efSEd Tanous std::vector<std::pair< 1311abe55efSEd Tanous std::string, sdbusplus::message::variant<std::string>>>>> 1323ae837c9SEd Tanous interfacesProperties; 133acb7cfb4SJennifer Lee 134c711bf86SEd Tanous sdbusplus::message::object_path objPath; 135acb7cfb4SJennifer Lee 1363ae837c9SEd Tanous m.read(objPath, interfacesProperties); // Read in the object path 137acb7cfb4SJennifer Lee // that was just created 138c711bf86SEd Tanous // std::string str_objpath = objPath.str; // keep a copy for 139acb7cfb4SJennifer Lee // constructing response message 140c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; // str_objpath; 1413ae837c9SEd Tanous for (auto &interface : interfacesProperties) 1421abe55efSEd Tanous { 143acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "interface = " << interface.first; 144acb7cfb4SJennifer Lee 1451abe55efSEd Tanous if (interface.first == 1461abe55efSEd Tanous "xyz.openbmc_project.Software.Activation") 1471abe55efSEd Tanous { 1481abe55efSEd Tanous // cancel timer only when 1491abe55efSEd Tanous // xyz.openbmc_project.Software.Activation interface is 1501abe55efSEd Tanous // added 151acb7cfb4SJennifer Lee boost::system::error_code ec; 152acb7cfb4SJennifer Lee timeout.cancel(ec); 1531abe55efSEd Tanous if (ec) 1541abe55efSEd Tanous { 155acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "error canceling timer " << ec; 156acb7cfb4SJennifer Lee } 157c711bf86SEd Tanous UpdateService::activateImage(objPath.str); // str_objpath); 158f12894f8SJason M. Bills redfish::messages::success(res); 159acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "ending response"; 160acb7cfb4SJennifer Lee res.end(); 161acb7cfb4SJennifer Lee fwUpdateMatcher = nullptr; 162acb7cfb4SJennifer Lee } 163acb7cfb4SJennifer Lee } 164acb7cfb4SJennifer Lee }; 165acb7cfb4SJennifer Lee 166acb7cfb4SJennifer Lee fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>( 167acb7cfb4SJennifer Lee *crow::connections::systemBus, 168acb7cfb4SJennifer Lee "interface='org.freedesktop.DBus.ObjectManager',type='signal'," 169acb7cfb4SJennifer Lee "member='InterfacesAdded',path='/xyz/openbmc_project/software'", 170acb7cfb4SJennifer Lee callback); 171acb7cfb4SJennifer Lee 172acb7cfb4SJennifer Lee std::string filepath( 173acb7cfb4SJennifer Lee "/tmp/images/" + 174acb7cfb4SJennifer Lee boost::uuids::to_string(boost::uuids::random_generator()())); 175acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Writing file to " << filepath; 176acb7cfb4SJennifer Lee std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary | 177acb7cfb4SJennifer Lee std::ofstream::trunc); 178acb7cfb4SJennifer Lee out << req.body; 179acb7cfb4SJennifer Lee out.close(); 180acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "file upload complete!!"; 181acb7cfb4SJennifer Lee } 182729dae72SJennifer Lee }; 183729dae72SJennifer Lee 1841abe55efSEd Tanous class SoftwareInventoryCollection : public Node 1851abe55efSEd Tanous { 186729dae72SJennifer Lee public: 187729dae72SJennifer Lee template <typename CrowApp> 1881abe55efSEd Tanous SoftwareInventoryCollection(CrowApp &app) : 1891abe55efSEd Tanous Node(app, "/redfish/v1/UpdateService/FirmwareInventory/") 1901abe55efSEd Tanous { 191729dae72SJennifer Lee Node::json["@odata.type"] = 192729dae72SJennifer Lee "#SoftwareInventoryCollection.SoftwareInventoryCollection"; 1936c4eb9deSJennifer Lee Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory"; 194729dae72SJennifer Lee Node::json["@odata.context"] = 195729dae72SJennifer Lee "/redfish/v1/" 196729dae72SJennifer Lee "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection"; 197729dae72SJennifer Lee Node::json["Name"] = "Software Inventory Collection"; 198729dae72SJennifer Lee 199729dae72SJennifer Lee entityPrivileges = { 200729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 201729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 202729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 203729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 204729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 205729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 206729dae72SJennifer Lee } 207729dae72SJennifer Lee 208729dae72SJennifer Lee private: 20955c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 2101abe55efSEd Tanous const std::vector<std::string> ¶ms) override 2111abe55efSEd Tanous { 212c711bf86SEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 21355c7b7a2SEd Tanous res.jsonValue = Node::json; 214c711bf86SEd Tanous 215c711bf86SEd Tanous crow::connections::systemBus->async_method_call( 216c711bf86SEd Tanous [asyncResp]( 217c711bf86SEd Tanous const boost::system::error_code ec, 2186c4eb9deSJennifer Lee const std::vector<std::pair< 2191abe55efSEd Tanous std::string, std::vector<std::pair< 2201abe55efSEd Tanous std::string, std::vector<std::string>>>>> 2216c4eb9deSJennifer Lee &subtree) { 2221abe55efSEd Tanous if (ec) 2231abe55efSEd Tanous { 224f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2256c4eb9deSJennifer Lee return; 226729dae72SJennifer Lee } 227c711bf86SEd Tanous asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); 228c711bf86SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 2296c4eb9deSJennifer Lee 2301abe55efSEd Tanous for (auto &obj : subtree) 2311abe55efSEd Tanous { 2321abe55efSEd Tanous const std::vector< 2331abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>> 2346c4eb9deSJennifer Lee &connections = obj.second; 2356c4eb9deSJennifer Lee 236f4b65ab1SJennifer Lee // if can't parse fw id then return 237*27826b5fSEd Tanous std::size_t idPos; 238*27826b5fSEd Tanous if ((idPos = obj.first.rfind("/")) == std::string::npos) 239f4b65ab1SJennifer Lee { 240f12894f8SJason M. Bills messages::internalError(asyncResp->res); 241f4b65ab1SJennifer Lee BMCWEB_LOG_DEBUG << "Can't parse firmware ID!!"; 242f4b65ab1SJennifer Lee return; 243f4b65ab1SJennifer Lee } 244f4b65ab1SJennifer Lee std::string swId = obj.first.substr(idPos + 1); 245f4b65ab1SJennifer Lee 2461abe55efSEd Tanous for (auto &conn : connections) 2471abe55efSEd Tanous { 248c711bf86SEd Tanous const std::string &connectionName = conn.first; 2491abe55efSEd Tanous BMCWEB_LOG_DEBUG << "connectionName = " 2501abe55efSEd Tanous << connectionName; 25155c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "obj.first = " << obj.first; 2526c4eb9deSJennifer Lee 25355c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 254f4b65ab1SJennifer Lee [asyncResp, 255f4b65ab1SJennifer Lee swId](const boost::system::error_code error_code, 256c711bf86SEd Tanous const VariantType &activation) { 2571abe55efSEd Tanous BMCWEB_LOG_DEBUG 2581abe55efSEd Tanous << "safe returned in lambda function"; 2591abe55efSEd Tanous if (error_code) 2601abe55efSEd Tanous { 261f12894f8SJason M. Bills messages::internalError(asyncResp->res); 2626c4eb9deSJennifer Lee return; 2636c4eb9deSJennifer Lee } 264c711bf86SEd Tanous 265f4b65ab1SJennifer Lee const std::string *swActivationStatus = 2661abe55efSEd Tanous mapbox::getPtr<const std::string>( 2671abe55efSEd Tanous activation); 268f4b65ab1SJennifer Lee if (swActivationStatus == nullptr) 2691abe55efSEd Tanous { 270f12894f8SJason M. Bills messages::internalError(asyncResp->res); 271acb7cfb4SJennifer Lee return; 272acb7cfb4SJennifer Lee } 273f4b65ab1SJennifer Lee if (swActivationStatus != nullptr && 274f4b65ab1SJennifer Lee *swActivationStatus != 275f4b65ab1SJennifer Lee "xyz.openbmc_project.Software." 276f4b65ab1SJennifer Lee "Activation." 277f4b65ab1SJennifer Lee "Activations.Active") 2781abe55efSEd Tanous { 279f4b65ab1SJennifer Lee // The activation status of this software is 280f4b65ab1SJennifer Lee // not currently active, so does not need to 281f4b65ab1SJennifer Lee // be listed in the response 282c711bf86SEd Tanous return; 283c711bf86SEd Tanous } 284c711bf86SEd Tanous nlohmann::json &members = 285c711bf86SEd Tanous asyncResp->res.jsonValue["Members"]; 286c711bf86SEd Tanous members.push_back( 287f4b65ab1SJennifer Lee {{"@odata.id", "/redfish/v1/UpdateService/" 2881abe55efSEd Tanous "FirmwareInventory/" + 289f4b65ab1SJennifer Lee swId}}); 2901abe55efSEd Tanous asyncResp->res 2911abe55efSEd Tanous .jsonValue["Members@odata.count"] = 292c711bf86SEd Tanous members.size(); 2936c4eb9deSJennifer Lee }, 2941abe55efSEd Tanous connectionName, obj.first, 2951abe55efSEd Tanous "org.freedesktop.DBus.Properties", "Get", 2961abe55efSEd Tanous "xyz.openbmc_project.Software.Activation", 297acb7cfb4SJennifer Lee "Activation"); 2986c4eb9deSJennifer Lee } 2996c4eb9deSJennifer Lee } 300c711bf86SEd Tanous }, 301c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", 302c711bf86SEd Tanous "/xyz/openbmc_project/object_mapper", 303c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 304c711bf86SEd Tanous "/xyz/openbmc_project/software", int32_t(1), 3051abe55efSEd Tanous std::array<const char *, 1>{ 3061abe55efSEd Tanous "xyz.openbmc_project.Software.Version"}); 307729dae72SJennifer Lee } 308729dae72SJennifer Lee }; 309c711bf86SEd Tanous 3101abe55efSEd Tanous class SoftwareInventory : public Node 3111abe55efSEd Tanous { 312729dae72SJennifer Lee public: 313729dae72SJennifer Lee template <typename CrowApp> 3141abe55efSEd Tanous SoftwareInventory(CrowApp &app) : 3151abe55efSEd Tanous Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/", 3161abe55efSEd Tanous std::string()) 3171abe55efSEd Tanous { 3181abe55efSEd Tanous Node::json["@odata.type"] = 3191abe55efSEd Tanous "#SoftwareInventory.v1_1_0.SoftwareInventory"; 320729dae72SJennifer Lee Node::json["@odata.context"] = 321729dae72SJennifer Lee "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory"; 322729dae72SJennifer Lee Node::json["Name"] = "Software Inventory"; 3236c4eb9deSJennifer Lee Node::json["Updateable"] = false; 324acb7cfb4SJennifer Lee Node::json["Status"]["Health"] = "OK"; 325acb7cfb4SJennifer Lee Node::json["Status"]["HealthRollup"] = "OK"; 326acb7cfb4SJennifer Lee Node::json["Status"]["State"] = "Enabled"; 327729dae72SJennifer Lee entityPrivileges = { 328729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 329729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 330729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 331729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 332729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 333729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 334729dae72SJennifer Lee } 335729dae72SJennifer Lee 336729dae72SJennifer Lee private: 33755c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 3381abe55efSEd Tanous const std::vector<std::string> ¶ms) override 3391abe55efSEd Tanous { 340c711bf86SEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 34155c7b7a2SEd Tanous res.jsonValue = Node::json; 3426c4eb9deSJennifer Lee 3431abe55efSEd Tanous if (params.size() != 1) 3441abe55efSEd Tanous { 345f12894f8SJason M. Bills messages::internalError(res); 346729dae72SJennifer Lee res.end(); 347729dae72SJennifer Lee return; 348729dae72SJennifer Lee } 349729dae72SJennifer Lee 3503ae837c9SEd Tanous std::shared_ptr<std::string> swId = 351c711bf86SEd Tanous std::make_shared<std::string>(params[0]); 352c711bf86SEd Tanous 35355c7b7a2SEd Tanous res.jsonValue["@odata.id"] = 3543ae837c9SEd Tanous "/redfish/v1/UpdateService/FirmwareInventory/" + *swId; 355c711bf86SEd Tanous 356c711bf86SEd Tanous crow::connections::systemBus->async_method_call( 3573ae837c9SEd Tanous [asyncResp, swId]( 358c711bf86SEd Tanous const boost::system::error_code ec, 3596c4eb9deSJennifer Lee const std::vector<std::pair< 3601abe55efSEd Tanous std::string, std::vector<std::pair< 3611abe55efSEd Tanous std::string, std::vector<std::string>>>>> 3626c4eb9deSJennifer Lee &subtree) { 36355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "doGet callback..."; 3641abe55efSEd Tanous if (ec) 3651abe55efSEd Tanous { 366f12894f8SJason M. Bills messages::internalError(asyncResp->res); 3676c4eb9deSJennifer Lee return; 3686c4eb9deSJennifer Lee } 3696c4eb9deSJennifer Lee 3701abe55efSEd Tanous for (const std::pair< 3711abe55efSEd Tanous std::string, 3721abe55efSEd Tanous std::vector< 3731abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>>> 3741abe55efSEd Tanous &obj : subtree) 3751abe55efSEd Tanous { 3763ae837c9SEd Tanous if (boost::ends_with(obj.first, *swId) != true) 3771abe55efSEd Tanous { 378acb7cfb4SJennifer Lee continue; 379acb7cfb4SJennifer Lee } 380acb7cfb4SJennifer Lee 381f4b65ab1SJennifer Lee if (obj.second.size() < 1) 3821abe55efSEd Tanous { 383acb7cfb4SJennifer Lee continue; 384acb7cfb4SJennifer Lee } 3856c4eb9deSJennifer Lee 38655c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 3871abe55efSEd Tanous [asyncResp, 3883ae837c9SEd Tanous swId](const boost::system::error_code error_code, 3891abe55efSEd Tanous const boost::container::flat_map< 3901abe55efSEd Tanous std::string, VariantType> &propertiesList) { 3911abe55efSEd Tanous if (error_code) 3921abe55efSEd Tanous { 393f12894f8SJason M. Bills messages::internalError(asyncResp->res); 3946c4eb9deSJennifer Lee return; 3956c4eb9deSJennifer Lee } 3961abe55efSEd Tanous boost::container::flat_map< 3971abe55efSEd Tanous std::string, VariantType>::const_iterator it = 3986c4eb9deSJennifer Lee propertiesList.find("Purpose"); 3991abe55efSEd Tanous if (it == propertiesList.end()) 4001abe55efSEd Tanous { 4011abe55efSEd Tanous BMCWEB_LOG_DEBUG 4021abe55efSEd Tanous << "Can't find property \"Purpose\"!"; 403f12894f8SJason M. Bills messages::propertyMissing(asyncResp->res, 404f12894f8SJason M. Bills "Purpose"); 4056c4eb9deSJennifer Lee return; 4066c4eb9deSJennifer Lee } 4073ae837c9SEd Tanous const std::string *swInvPurpose = 408acb7cfb4SJennifer Lee mapbox::getPtr<const std::string>(it->second); 4093ae837c9SEd Tanous if (swInvPurpose == nullptr) 4101abe55efSEd Tanous { 4111abe55efSEd Tanous BMCWEB_LOG_DEBUG 4121abe55efSEd Tanous << "wrong types for property\"Purpose\"!"; 413f12894f8SJason M. Bills messages::propertyValueTypeError(asyncResp->res, 414f12894f8SJason M. Bills "", "Purpose"); 415acb7cfb4SJennifer Lee return; 416acb7cfb4SJennifer Lee } 417c711bf86SEd Tanous 4183ae837c9SEd Tanous BMCWEB_LOG_DEBUG << "swInvPurpose = " 4193ae837c9SEd Tanous << *swInvPurpose; 420c711bf86SEd Tanous it = propertiesList.find("Version"); 4211abe55efSEd Tanous if (it == propertiesList.end()) 4221abe55efSEd Tanous { 4231abe55efSEd Tanous BMCWEB_LOG_DEBUG 4241abe55efSEd Tanous << "Can't find property \"Version\"!"; 425f12894f8SJason M. Bills messages::propertyMissing(asyncResp->res, 426f12894f8SJason M. Bills "Version"); 427c711bf86SEd Tanous return; 428acb7cfb4SJennifer Lee } 429acb7cfb4SJennifer Lee 430f4b65ab1SJennifer Lee BMCWEB_LOG_DEBUG << "Version found!"; 431c711bf86SEd Tanous 432f4b65ab1SJennifer Lee const std::string *version = 433f4b65ab1SJennifer Lee mapbox::getPtr<const std::string>(it->second); 434f4b65ab1SJennifer Lee 435f4b65ab1SJennifer Lee if (version == nullptr) 4361abe55efSEd Tanous { 4371abe55efSEd Tanous BMCWEB_LOG_DEBUG 4381abe55efSEd Tanous << "Can't find property \"Version\"!"; 439f12894f8SJason M. Bills 440f12894f8SJason M. Bills messages::propertyValueTypeError(asyncResp->res, 441f12894f8SJason M. Bills "", "Version"); 4426c4eb9deSJennifer Lee return; 4436c4eb9deSJennifer Lee } 444c711bf86SEd Tanous asyncResp->res.jsonValue["Version"] = *version; 4453ae837c9SEd Tanous asyncResp->res.jsonValue["Id"] = *swId; 4466c4eb9deSJennifer Lee }, 447c711bf86SEd Tanous obj.second[0].first, obj.first, 448c711bf86SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 449c711bf86SEd Tanous "xyz.openbmc_project.Software.Version"); 4506c4eb9deSJennifer Lee } 451c711bf86SEd Tanous }, 452c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", 453c711bf86SEd Tanous "/xyz/openbmc_project/object_mapper", 454c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 455c711bf86SEd Tanous "/xyz/openbmc_project/software", int32_t(1), 4561abe55efSEd Tanous std::array<const char *, 1>{ 4571abe55efSEd Tanous "xyz.openbmc_project.Software.Version"}); 4586c4eb9deSJennifer Lee } 459729dae72SJennifer Lee }; 460729dae72SJennifer Lee 461729dae72SJennifer Lee } // namespace redfish 462