xref: /openbmc/estoraged/src/getConfig.cpp (revision 3cf9e806)
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(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 
getConfiguration()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 
~GetStorageConfiguration()105 GetStorageConfiguration::~GetStorageConfiguration()
106 {
107     callback(respData);
108 }
109 
110 } // namespace estoraged
111