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" 19*1abe55efSEd Tanous 20729dae72SJennifer Lee #include <boost/container/flat_map.hpp> 21729dae72SJennifer Lee 22*1abe55efSEd Tanous namespace redfish 23*1abe55efSEd Tanous { 24acb7cfb4SJennifer Lee static std::unique_ptr<sdbusplus::bus::match::match> fwUpdateMatcher; 25729dae72SJennifer Lee 26*1abe55efSEd Tanous class UpdateService : public Node 27*1abe55efSEd Tanous { 28729dae72SJennifer Lee public: 29*1abe55efSEd Tanous UpdateService(CrowApp &app) : Node(app, "/redfish/v1/UpdateService/") 30*1abe55efSEd Tanous { 31729dae72SJennifer Lee Node::json["@odata.type"] = "#UpdateService.v1_2_0.UpdateService"; 32729dae72SJennifer Lee Node::json["@odata.id"] = "/redfish/v1/UpdateService"; 33729dae72SJennifer Lee Node::json["@odata.context"] = 34729dae72SJennifer Lee "/redfish/v1/$metadata#UpdateService.UpdateService"; 35729dae72SJennifer Lee Node::json["Id"] = "UpdateService"; 36729dae72SJennifer Lee Node::json["Description"] = "Service for Software Update"; 37729dae72SJennifer Lee Node::json["Name"] = "Update Service"; 38acb7cfb4SJennifer Lee Node::json["HttpPushUri"] = "/redfish/v1/UpdateService"; 39c711bf86SEd Tanous // UpdateService cannot be disabled 40c711bf86SEd Tanous Node::json["ServiceEnabled"] = true; 416c4eb9deSJennifer Lee Node::json["FirmwareInventory"] = { 426c4eb9deSJennifer Lee {"@odata.id", "/redfish/v1/UpdateService/FirmwareInventory"}}; 43729dae72SJennifer Lee 44729dae72SJennifer Lee entityPrivileges = { 45729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 46729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 47729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 48729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 49729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 50729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 51729dae72SJennifer Lee } 52729dae72SJennifer Lee 53729dae72SJennifer Lee private: 5455c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 55*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 56*1abe55efSEd Tanous { 5755c7b7a2SEd Tanous res.jsonValue = Node::json; 58729dae72SJennifer Lee res.end(); 59729dae72SJennifer Lee } 60*1abe55efSEd Tanous static void activateImage(const std::string &objPath) 61*1abe55efSEd Tanous { 62acb7cfb4SJennifer Lee crow::connections::systemBus->async_method_call( 63c711bf86SEd Tanous [objPath](const boost::system::error_code error_code) { 64*1abe55efSEd Tanous if (error_code) 65*1abe55efSEd Tanous { 66acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "error_code = " << error_code; 67acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "error msg = " << error_code.message(); 68acb7cfb4SJennifer Lee } 69acb7cfb4SJennifer Lee }, 70c711bf86SEd Tanous "xyz.openbmc_project.Software.BMC.Updater", objPath, 71acb7cfb4SJennifer Lee "org.freedesktop.DBus.Properties", "Set", 72acb7cfb4SJennifer Lee "xyz.openbmc_project.Software.Activation", "RequestedActivation", 73acb7cfb4SJennifer Lee sdbusplus::message::variant<std::string>( 74acb7cfb4SJennifer Lee "xyz.openbmc_project.Software.Activation.RequestedActivations." 75acb7cfb4SJennifer Lee "Active")); 76acb7cfb4SJennifer Lee } 77acb7cfb4SJennifer Lee void doPost(crow::Response &res, const crow::Request &req, 78*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 79*1abe55efSEd Tanous { 80acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "doPost..."; 81acb7cfb4SJennifer Lee 82acb7cfb4SJennifer Lee // Only allow one FW update at a time 83*1abe55efSEd Tanous if (fwUpdateMatcher != nullptr) 84*1abe55efSEd Tanous { 85acb7cfb4SJennifer Lee res.addHeader("Retry-After", "30"); 86acb7cfb4SJennifer Lee res.result(boost::beast::http::status::service_unavailable); 87acb7cfb4SJennifer Lee res.jsonValue = messages::serviceTemporarilyUnavailable("3"); 88acb7cfb4SJennifer Lee res.end(); 89acb7cfb4SJennifer Lee return; 90acb7cfb4SJennifer Lee } 91acb7cfb4SJennifer Lee // Make this const static so it survives outside this method 92*1abe55efSEd Tanous static boost::asio::deadline_timer timeout( 93*1abe55efSEd 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; 99*1abe55efSEd Tanous if (ec == boost::asio::error::operation_aborted) 100*1abe55efSEd Tanous { 101acb7cfb4SJennifer Lee // expected, we were canceled before the timer completed. 102acb7cfb4SJennifer Lee return; 103acb7cfb4SJennifer Lee } 104*1abe55efSEd Tanous BMCWEB_LOG_ERROR 105*1abe55efSEd Tanous << "Timed out waiting for firmware object being created"; 106*1abe55efSEd Tanous BMCWEB_LOG_ERROR 107*1abe55efSEd Tanous << "FW image may has already been uploaded to server"; 108*1abe55efSEd Tanous if (ec) 109*1abe55efSEd Tanous { 110acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "Async_wait failed" << ec; 111acb7cfb4SJennifer Lee return; 112acb7cfb4SJennifer Lee } 113acb7cfb4SJennifer Lee 114acb7cfb4SJennifer Lee res.result(boost::beast::http::status::internal_server_error); 115acb7cfb4SJennifer Lee res.jsonValue = redfish::messages::internalError(); 116acb7cfb4SJennifer Lee res.end(); 117acb7cfb4SJennifer Lee }); 118acb7cfb4SJennifer Lee 119acb7cfb4SJennifer Lee auto callback = [&res](sdbusplus::message::message &m) { 120acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Match fired"; 121acb7cfb4SJennifer Lee bool flag = false; 122acb7cfb4SJennifer Lee 123*1abe55efSEd Tanous if (m.is_method_error()) 124*1abe55efSEd Tanous { 125acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Dbus method error!!!"; 126acb7cfb4SJennifer Lee res.end(); 127acb7cfb4SJennifer Lee return; 128acb7cfb4SJennifer Lee } 129acb7cfb4SJennifer Lee std::vector<std::pair< 130acb7cfb4SJennifer Lee std::string, 131*1abe55efSEd Tanous std::vector<std::pair< 132*1abe55efSEd Tanous std::string, sdbusplus::message::variant<std::string>>>>> 133acb7cfb4SJennifer Lee interfaces_properties; 134acb7cfb4SJennifer Lee 135c711bf86SEd Tanous sdbusplus::message::object_path objPath; 136acb7cfb4SJennifer Lee 137c711bf86SEd Tanous m.read(objPath, interfaces_properties); // Read in the object path 138acb7cfb4SJennifer Lee // that was just created 139c711bf86SEd Tanous // std::string str_objpath = objPath.str; // keep a copy for 140acb7cfb4SJennifer Lee // constructing response message 141c711bf86SEd Tanous BMCWEB_LOG_DEBUG << "obj path = " << objPath.str; // str_objpath; 142*1abe55efSEd Tanous for (auto &interface : interfaces_properties) 143*1abe55efSEd Tanous { 144acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "interface = " << interface.first; 145acb7cfb4SJennifer Lee 146*1abe55efSEd Tanous if (interface.first == 147*1abe55efSEd Tanous "xyz.openbmc_project.Software.Activation") 148*1abe55efSEd Tanous { 149*1abe55efSEd Tanous // cancel timer only when 150*1abe55efSEd Tanous // xyz.openbmc_project.Software.Activation interface is 151*1abe55efSEd Tanous // added 152acb7cfb4SJennifer Lee boost::system::error_code ec; 153acb7cfb4SJennifer Lee timeout.cancel(ec); 154*1abe55efSEd Tanous if (ec) 155*1abe55efSEd Tanous { 156acb7cfb4SJennifer Lee BMCWEB_LOG_ERROR << "error canceling timer " << ec; 157acb7cfb4SJennifer Lee } 158c711bf86SEd Tanous UpdateService::activateImage(objPath.str); // str_objpath); 159acb7cfb4SJennifer Lee res.jsonValue = redfish::messages::success(); 160acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "ending response"; 161acb7cfb4SJennifer Lee res.end(); 162acb7cfb4SJennifer Lee fwUpdateMatcher = nullptr; 163acb7cfb4SJennifer Lee } 164acb7cfb4SJennifer Lee } 165acb7cfb4SJennifer Lee }; 166acb7cfb4SJennifer Lee 167acb7cfb4SJennifer Lee fwUpdateMatcher = std::make_unique<sdbusplus::bus::match::match>( 168acb7cfb4SJennifer Lee *crow::connections::systemBus, 169acb7cfb4SJennifer Lee "interface='org.freedesktop.DBus.ObjectManager',type='signal'," 170acb7cfb4SJennifer Lee "member='InterfacesAdded',path='/xyz/openbmc_project/software'", 171acb7cfb4SJennifer Lee callback); 172acb7cfb4SJennifer Lee 173acb7cfb4SJennifer Lee std::string filepath( 174acb7cfb4SJennifer Lee "/tmp/images/" + 175acb7cfb4SJennifer Lee boost::uuids::to_string(boost::uuids::random_generator()())); 176acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "Writing file to " << filepath; 177acb7cfb4SJennifer Lee std::ofstream out(filepath, std::ofstream::out | std::ofstream::binary | 178acb7cfb4SJennifer Lee std::ofstream::trunc); 179acb7cfb4SJennifer Lee out << req.body; 180acb7cfb4SJennifer Lee out.close(); 181acb7cfb4SJennifer Lee BMCWEB_LOG_DEBUG << "file upload complete!!"; 182acb7cfb4SJennifer Lee } 183729dae72SJennifer Lee }; 184729dae72SJennifer Lee 185*1abe55efSEd Tanous class SoftwareInventoryCollection : public Node 186*1abe55efSEd Tanous { 187729dae72SJennifer Lee public: 188729dae72SJennifer Lee template <typename CrowApp> 189*1abe55efSEd Tanous SoftwareInventoryCollection(CrowApp &app) : 190*1abe55efSEd Tanous Node(app, "/redfish/v1/UpdateService/FirmwareInventory/") 191*1abe55efSEd Tanous { 192729dae72SJennifer Lee Node::json["@odata.type"] = 193729dae72SJennifer Lee "#SoftwareInventoryCollection.SoftwareInventoryCollection"; 1946c4eb9deSJennifer Lee Node::json["@odata.id"] = "/redfish/v1/UpdateService/FirmwareInventory"; 195729dae72SJennifer Lee Node::json["@odata.context"] = 196729dae72SJennifer Lee "/redfish/v1/" 197729dae72SJennifer Lee "$metadata#SoftwareInventoryCollection.SoftwareInventoryCollection"; 198729dae72SJennifer Lee Node::json["Name"] = "Software Inventory Collection"; 199729dae72SJennifer Lee 200729dae72SJennifer Lee entityPrivileges = { 201729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 202729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 203729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 204729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 205729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 206729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 207729dae72SJennifer Lee } 208729dae72SJennifer Lee 209729dae72SJennifer Lee private: 21055c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 211*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 212*1abe55efSEd Tanous { 213c711bf86SEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 21455c7b7a2SEd Tanous res.jsonValue = Node::json; 215c711bf86SEd Tanous 216c711bf86SEd Tanous crow::connections::systemBus->async_method_call( 217c711bf86SEd Tanous [asyncResp]( 218c711bf86SEd Tanous const boost::system::error_code ec, 2196c4eb9deSJennifer Lee const std::vector<std::pair< 220*1abe55efSEd Tanous std::string, std::vector<std::pair< 221*1abe55efSEd Tanous std::string, std::vector<std::string>>>>> 2226c4eb9deSJennifer Lee &subtree) { 223*1abe55efSEd Tanous if (ec) 224*1abe55efSEd Tanous { 225c711bf86SEd Tanous asyncResp->res.result( 226c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 2276c4eb9deSJennifer Lee return; 228729dae72SJennifer Lee } 229c711bf86SEd Tanous asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); 230c711bf86SEd Tanous asyncResp->res.jsonValue["Members@odata.count"] = 0; 2316c4eb9deSJennifer Lee 232*1abe55efSEd Tanous for (auto &obj : subtree) 233*1abe55efSEd Tanous { 234*1abe55efSEd Tanous const std::vector< 235*1abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>> 2366c4eb9deSJennifer Lee &connections = obj.second; 2376c4eb9deSJennifer Lee 238*1abe55efSEd Tanous for (auto &conn : connections) 239*1abe55efSEd Tanous { 240c711bf86SEd Tanous const std::string &connectionName = conn.first; 241*1abe55efSEd Tanous BMCWEB_LOG_DEBUG << "connectionName = " 242*1abe55efSEd Tanous << connectionName; 24355c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "obj.first = " << obj.first; 2446c4eb9deSJennifer Lee 24555c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 246*1abe55efSEd Tanous [asyncResp]( 247*1abe55efSEd Tanous const boost::system::error_code error_code, 248c711bf86SEd Tanous const VariantType &activation) { 249*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 250*1abe55efSEd Tanous << "safe returned in lambda function"; 251*1abe55efSEd Tanous if (error_code) 252*1abe55efSEd Tanous { 253acb7cfb4SJennifer Lee asyncResp->res.result( 254*1abe55efSEd Tanous boost::beast::http::status:: 255*1abe55efSEd Tanous internal_server_error); 2566c4eb9deSJennifer Lee return; 2576c4eb9deSJennifer Lee } 258c711bf86SEd Tanous 259c711bf86SEd Tanous const std::string *sw_inv_purpose = 260*1abe55efSEd Tanous mapbox::getPtr<const std::string>( 261*1abe55efSEd Tanous activation); 262*1abe55efSEd Tanous if (sw_inv_purpose == nullptr) 263*1abe55efSEd Tanous { 264c711bf86SEd Tanous asyncResp->res.result( 265*1abe55efSEd Tanous boost::beast::http::status:: 266*1abe55efSEd Tanous internal_server_error); 267acb7cfb4SJennifer Lee return; 268acb7cfb4SJennifer Lee } 269*1abe55efSEd Tanous std::size_t last_pos = 270*1abe55efSEd Tanous sw_inv_purpose->rfind("."); 271*1abe55efSEd Tanous if (last_pos == std::string::npos) 272*1abe55efSEd Tanous { 273c711bf86SEd Tanous asyncResp->res.result( 274*1abe55efSEd Tanous boost::beast::http::status:: 275*1abe55efSEd Tanous internal_server_error); 276c711bf86SEd Tanous return; 277c711bf86SEd Tanous } 278c711bf86SEd Tanous nlohmann::json &members = 279c711bf86SEd Tanous asyncResp->res.jsonValue["Members"]; 280c711bf86SEd Tanous members.push_back( 281*1abe55efSEd Tanous {{"@odata.id", "/redfish/v1/UpdateService/" 282*1abe55efSEd Tanous "FirmwareInventory/" + 283*1abe55efSEd Tanous sw_inv_purpose->substr( 284*1abe55efSEd Tanous last_pos + 1)}}); 285*1abe55efSEd Tanous asyncResp->res 286*1abe55efSEd Tanous .jsonValue["Members@odata.count"] = 287c711bf86SEd Tanous members.size(); 2886c4eb9deSJennifer Lee }, 289*1abe55efSEd Tanous connectionName, obj.first, 290*1abe55efSEd Tanous "org.freedesktop.DBus.Properties", "Get", 291*1abe55efSEd Tanous "xyz.openbmc_project.Software.Activation", 292acb7cfb4SJennifer Lee "Activation"); 2936c4eb9deSJennifer Lee } 2946c4eb9deSJennifer Lee } 295c711bf86SEd Tanous }, 296c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", 297c711bf86SEd Tanous "/xyz/openbmc_project/object_mapper", 298c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 299c711bf86SEd Tanous "/xyz/openbmc_project/software", int32_t(1), 300*1abe55efSEd Tanous std::array<const char *, 1>{ 301*1abe55efSEd Tanous "xyz.openbmc_project.Software.Version"}); 302729dae72SJennifer Lee } 303729dae72SJennifer Lee }; 304c711bf86SEd Tanous 305*1abe55efSEd Tanous class SoftwareInventory : public Node 306*1abe55efSEd Tanous { 307729dae72SJennifer Lee public: 308729dae72SJennifer Lee template <typename CrowApp> 309*1abe55efSEd Tanous SoftwareInventory(CrowApp &app) : 310*1abe55efSEd Tanous Node(app, "/redfish/v1/UpdateService/FirmwareInventory/<str>/", 311*1abe55efSEd Tanous std::string()) 312*1abe55efSEd Tanous { 313*1abe55efSEd Tanous Node::json["@odata.type"] = 314*1abe55efSEd Tanous "#SoftwareInventory.v1_1_0.SoftwareInventory"; 315729dae72SJennifer Lee Node::json["@odata.context"] = 316729dae72SJennifer Lee "/redfish/v1/$metadata#SoftwareInventory.SoftwareInventory"; 317729dae72SJennifer Lee Node::json["Name"] = "Software Inventory"; 3186c4eb9deSJennifer Lee Node::json["Updateable"] = false; 319acb7cfb4SJennifer Lee Node::json["Status"]["Health"] = "OK"; 320acb7cfb4SJennifer Lee Node::json["Status"]["HealthRollup"] = "OK"; 321acb7cfb4SJennifer Lee Node::json["Status"]["State"] = "Enabled"; 322729dae72SJennifer Lee entityPrivileges = { 323729dae72SJennifer Lee {boost::beast::http::verb::get, {{"Login"}}}, 324729dae72SJennifer Lee {boost::beast::http::verb::head, {{"Login"}}}, 325729dae72SJennifer Lee {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, 326729dae72SJennifer Lee {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, 327729dae72SJennifer Lee {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, 328729dae72SJennifer Lee {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; 329729dae72SJennifer Lee } 330729dae72SJennifer Lee 331729dae72SJennifer Lee private: 33255c7b7a2SEd Tanous void doGet(crow::Response &res, const crow::Request &req, 333*1abe55efSEd Tanous const std::vector<std::string> ¶ms) override 334*1abe55efSEd Tanous { 335c711bf86SEd Tanous std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 33655c7b7a2SEd Tanous res.jsonValue = Node::json; 3376c4eb9deSJennifer Lee 338*1abe55efSEd Tanous if (params.size() != 1) 339*1abe55efSEd Tanous { 340729dae72SJennifer Lee res.result(boost::beast::http::status::internal_server_error); 341acb7cfb4SJennifer Lee res.jsonValue = messages::internalError(); 342729dae72SJennifer Lee res.end(); 343729dae72SJennifer Lee return; 344729dae72SJennifer Lee } 345729dae72SJennifer Lee 346c711bf86SEd Tanous std::shared_ptr<std::string> sw_id = 347c711bf86SEd Tanous std::make_shared<std::string>(params[0]); 348c711bf86SEd Tanous 34955c7b7a2SEd Tanous res.jsonValue["@odata.id"] = 350c711bf86SEd Tanous "/redfish/v1/UpdateService/FirmwareInventory/" + *sw_id; 351c711bf86SEd Tanous 352c711bf86SEd Tanous crow::connections::systemBus->async_method_call( 353c711bf86SEd Tanous [asyncResp, sw_id]( 354c711bf86SEd Tanous const boost::system::error_code ec, 3556c4eb9deSJennifer Lee const std::vector<std::pair< 356*1abe55efSEd Tanous std::string, std::vector<std::pair< 357*1abe55efSEd Tanous std::string, std::vector<std::string>>>>> 3586c4eb9deSJennifer Lee &subtree) { 35955c7b7a2SEd Tanous BMCWEB_LOG_DEBUG << "doGet callback..."; 360*1abe55efSEd Tanous if (ec) 361*1abe55efSEd Tanous { 362c711bf86SEd Tanous asyncResp->res.result( 363c711bf86SEd Tanous boost::beast::http::status::internal_server_error); 3646c4eb9deSJennifer Lee return; 3656c4eb9deSJennifer Lee } 3666c4eb9deSJennifer Lee 367*1abe55efSEd Tanous for (const std::pair< 368*1abe55efSEd Tanous std::string, 369*1abe55efSEd Tanous std::vector< 370*1abe55efSEd Tanous std::pair<std::string, std::vector<std::string>>>> 371*1abe55efSEd Tanous &obj : subtree) 372*1abe55efSEd Tanous { 373*1abe55efSEd Tanous if (boost::ends_with(obj.first, *sw_id) != true) 374*1abe55efSEd Tanous { 375acb7cfb4SJennifer Lee continue; 376acb7cfb4SJennifer Lee } 377acb7cfb4SJennifer Lee 378*1abe55efSEd Tanous if (obj.second.size() <= 1) 379*1abe55efSEd Tanous { 380acb7cfb4SJennifer Lee continue; 381acb7cfb4SJennifer Lee } 3826c4eb9deSJennifer Lee 38355c7b7a2SEd Tanous crow::connections::systemBus->async_method_call( 384*1abe55efSEd Tanous [asyncResp, 385*1abe55efSEd Tanous sw_id](const boost::system::error_code error_code, 386*1abe55efSEd Tanous const boost::container::flat_map< 387*1abe55efSEd Tanous std::string, VariantType> &propertiesList) { 388*1abe55efSEd Tanous if (error_code) 389*1abe55efSEd Tanous { 390c711bf86SEd Tanous asyncResp->res.result( 391*1abe55efSEd Tanous boost::beast::http::status:: 392*1abe55efSEd Tanous internal_server_error); 3936c4eb9deSJennifer Lee return; 3946c4eb9deSJennifer Lee } 395*1abe55efSEd Tanous boost::container::flat_map< 396*1abe55efSEd Tanous std::string, VariantType>::const_iterator it = 3976c4eb9deSJennifer Lee propertiesList.find("Purpose"); 398*1abe55efSEd Tanous if (it == propertiesList.end()) 399*1abe55efSEd Tanous { 400*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 401*1abe55efSEd Tanous << "Can't find property \"Purpose\"!"; 402c711bf86SEd Tanous asyncResp->res.result( 403*1abe55efSEd Tanous boost::beast::http::status:: 404*1abe55efSEd Tanous internal_server_error); 4056c4eb9deSJennifer Lee return; 4066c4eb9deSJennifer Lee } 407acb7cfb4SJennifer Lee const std::string *sw_inv_purpose = 408acb7cfb4SJennifer Lee mapbox::getPtr<const std::string>(it->second); 409*1abe55efSEd Tanous if (sw_inv_purpose == nullptr) 410*1abe55efSEd Tanous { 411*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 412*1abe55efSEd Tanous << "wrong types for property\"Purpose\"!"; 413c711bf86SEd Tanous asyncResp->res.result( 414*1abe55efSEd Tanous boost::beast::http::status:: 415*1abe55efSEd Tanous internal_server_error); 416acb7cfb4SJennifer Lee return; 417acb7cfb4SJennifer Lee } 418c711bf86SEd Tanous 419*1abe55efSEd Tanous BMCWEB_LOG_DEBUG << "sw_inv_purpose = " 420*1abe55efSEd Tanous << *sw_inv_purpose; 421*1abe55efSEd Tanous if (boost::ends_with(*sw_inv_purpose, "." + *sw_id)) 422*1abe55efSEd Tanous { 423c711bf86SEd Tanous it = propertiesList.find("Version"); 424*1abe55efSEd Tanous if (it == propertiesList.end()) 425*1abe55efSEd Tanous { 426*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 427*1abe55efSEd Tanous << "Can't find property \"Version\"!"; 428c711bf86SEd Tanous asyncResp->res.result( 429*1abe55efSEd Tanous boost::beast::http::status:: 430*1abe55efSEd Tanous internal_server_error); 431c711bf86SEd Tanous return; 432acb7cfb4SJennifer Lee } 433acb7cfb4SJennifer Lee 434acb7cfb4SJennifer Lee const std::string *version = 435*1abe55efSEd Tanous mapbox::getPtr<const std::string>( 436*1abe55efSEd Tanous it->second); 437c711bf86SEd Tanous 438*1abe55efSEd Tanous if (version != nullptr) 439*1abe55efSEd Tanous { 440*1abe55efSEd Tanous BMCWEB_LOG_DEBUG 441*1abe55efSEd Tanous << "Can't find property \"Version\"!"; 442c711bf86SEd Tanous asyncResp->res.result( 443*1abe55efSEd Tanous boost::beast::http::status:: 444*1abe55efSEd Tanous internal_server_error); 4456c4eb9deSJennifer Lee return; 4466c4eb9deSJennifer Lee } 447c711bf86SEd Tanous asyncResp->res.jsonValue["Version"] = *version; 448c711bf86SEd Tanous asyncResp->res.jsonValue["Id"] = *sw_id; 4496c4eb9deSJennifer Lee } 4506c4eb9deSJennifer Lee }, 451c711bf86SEd Tanous obj.second[0].first, obj.first, 452c711bf86SEd Tanous "org.freedesktop.DBus.Properties", "GetAll", 453c711bf86SEd Tanous "xyz.openbmc_project.Software.Version"); 4546c4eb9deSJennifer Lee } 455c711bf86SEd Tanous }, 456c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", 457c711bf86SEd Tanous "/xyz/openbmc_project/object_mapper", 458c711bf86SEd Tanous "xyz.openbmc_project.ObjectMapper", "GetSubTree", 459c711bf86SEd Tanous "/xyz/openbmc_project/software", int32_t(1), 460*1abe55efSEd Tanous std::array<const char *, 1>{ 461*1abe55efSEd Tanous "xyz.openbmc_project.Software.Version"}); 4626c4eb9deSJennifer Lee } 463729dae72SJennifer Lee }; 464729dae72SJennifer Lee 465729dae72SJennifer Lee } // namespace redfish 466