xref: /openbmc/estoraged/src/getConfig.cpp (revision 15b63e12)
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 
getStorageInfo(const std::string & path,const std::string & owner,size_t retries)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 
getConfiguration()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 
~GetStorageConfiguration()104 GetStorageConfiguration::~GetStorageConfiguration()
105 {
106     callback(respData);
107 }
108 
109 } // namespace estoraged
110