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(const std::string& path, 32 const std::string& owner, 33 size_t retries) 34 { 35 std::shared_ptr<GetStorageConfiguration> self = shared_from_this(); 36 self->dbusConnection->async_method_call( 37 [self, path, owner, retries]( 38 const boost::system::error_code ec, 39 boost::container::flat_map<std::string, BasicVariantType>& data) { 40 if (ec) 41 { 42 lg2::error( 43 "Error getting properties for {PATH}: {RETRIES} retries left", 44 "PATH", path, "RETRIES", retries - 1, "REDFISH_MESSAGE_ID", 45 std::string("OpenBMC.0.1.GetStorageInfoFail")); 46 if (retries == 0U) 47 { 48 return; 49 } 50 51 auto timer = std::make_shared<boost::asio::steady_timer>( 52 self->dbusConnection->get_io_context()); 53 timer->expires_after(std::chrono::seconds(10)); 54 timer->async_wait([self, timer, path, owner, 55 retries](boost::system::error_code ec) { 56 if (ec) 57 { 58 lg2::error("Timer error!"); 59 return; 60 } 61 self->getStorageInfo(path, owner, retries - 1); 62 }); 63 64 return; 65 } 66 67 self->respData[path] = std::move(data); 68 }, 69 owner, path, "org.freedesktop.DBus.Properties", "GetAll", 70 emmcConfigInterface); 71 } 72 73 void GetStorageConfiguration::getConfiguration() 74 { 75 std::shared_ptr<GetStorageConfiguration> self = shared_from_this(); 76 dbusConnection->async_method_call( 77 [self](const boost::system::error_code ec, const GetSubTreeType& ret) { 78 if (ec) 79 { 80 lg2::error("Error calling mapper"); 81 return; 82 } 83 for (const auto& [objPath, objDict] : ret) 84 { 85 if (objDict.empty()) 86 { 87 return; 88 } 89 const std::string& objOwner = objDict.begin()->first; 90 /* Look for the config interface exposed by this object. */ 91 for (const std::string& interface : objDict.begin()->second) 92 { 93 if (interface.compare(emmcConfigInterface) == 0) 94 { 95 /* Get the properties exposed by this interface. */ 96 self->getStorageInfo(objPath, objOwner); 97 } 98 } 99 } 100 }, 101 mapper::busName, mapper::path, mapper::interface, mapper::subtree, "/", 102 0, std::vector<const char*>(1, emmcConfigInterface)); 103 } 104 105 GetStorageConfiguration::~GetStorageConfiguration() 106 { 107 callback(respData); 108 } 109 110 } // namespace estoraged 111