1 2 #include "getConfig.hpp" 3 4 #include <boost/asio/steady_timer.hpp> 5 #include <phosphor-logging/lg2.hpp> 6 #include <sdbusplus/asio/connection.hpp> 7 8 #include <chrono> 9 #include <cstdlib> 10 #include <memory> 11 #include <string> 12 #include <utility> 13 #include <variant> 14 #include <vector> 15 16 namespace estoraged 17 { 18 19 namespace mapper 20 { 21 constexpr const char* busName = "xyz.openbmc_project.ObjectMapper"; 22 constexpr const char* path = "/xyz/openbmc_project/object_mapper"; 23 constexpr const char* interface = "xyz.openbmc_project.ObjectMapper"; 24 constexpr const char* subtree = "GetSubTree"; 25 } // namespace mapper 26 27 using GetSubTreeType = std::vector< 28 std::pair<std::string, 29 std::vector<std::pair<std::string, std::vector<std::string>>>>>; 30 31 void GetStorageConfiguration::getStorageInfo( 32 const std::string& path, const std::string& owner, size_t retries) 33 { 34 std::shared_ptr<GetStorageConfiguration> self = shared_from_this(); 35 self->dbusConnection->async_method_call( 36 [self, path, owner, retries]( 37 const boost::system::error_code ec, 38 boost::container::flat_map<std::string, BasicVariantType>& data) { 39 if (ec) 40 { 41 lg2::error( 42 "Error getting properties for {PATH}: {RETRIES} retries left", 43 "PATH", path, "RETRIES", retries - 1, "REDFISH_MESSAGE_ID", 44 std::string("OpenBMC.0.1.GetStorageInfoFail")); 45 if (retries == 0U) 46 { 47 return; 48 } 49 50 auto timer = std::make_shared<boost::asio::steady_timer>( 51 self->dbusConnection->get_io_context()); 52 timer->expires_after(std::chrono::seconds(10)); 53 timer->async_wait([self, timer, path, owner, 54 retries](boost::system::error_code ec) { 55 if (ec) 56 { 57 lg2::error("Timer error!"); 58 return; 59 } 60 self->getStorageInfo(path, owner, retries - 1); 61 }); 62 63 return; 64 } 65 66 self->respData[path] = std::move(data); 67 }, 68 owner, path, "org.freedesktop.DBus.Properties", "GetAll", 69 emmcConfigInterface); 70 } 71 72 void GetStorageConfiguration::getConfiguration() 73 { 74 std::shared_ptr<GetStorageConfiguration> self = shared_from_this(); 75 dbusConnection->async_method_call( 76 [self](const boost::system::error_code ec, const GetSubTreeType& ret) { 77 if (ec) 78 { 79 lg2::error("Error calling mapper"); 80 return; 81 } 82 for (const auto& [objPath, objDict] : ret) 83 { 84 if (objDict.empty()) 85 { 86 return; 87 } 88 const std::string& objOwner = objDict.begin()->first; 89 /* Look for the config interface exposed by this object. */ 90 for (const std::string& interface : objDict.begin()->second) 91 { 92 if (interface.compare(emmcConfigInterface) == 0) 93 { 94 /* Get the properties exposed by this interface. */ 95 self->getStorageInfo(objPath, objOwner); 96 } 97 } 98 } 99 }, 100 mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/", 101 0, std::vector<const char*>(1, emmcConfigInterface)); 102 } 103 104 GetStorageConfiguration::~GetStorageConfiguration() 105 { 106 callback(respData); 107 } 108 109 } // namespace estoraged 110