blob: ad5f99717574a388ec0843fc7bee9c22988a6e0d [file] [log] [blame]
Tom Josephbe703f72017-03-09 12:34:35 +05301#include "utils.hpp"
Ratan Guptacc8feb42017-07-25 21:52:10 +05302#include "host-ipmid/ipmid-api.h"
3#include <phosphor-logging/log.hpp>
4#include <phosphor-logging/elog-errors.hpp>
5#include "xyz/openbmc_project/Common/error.hpp"
Tom Josephbe703f72017-03-09 12:34:35 +05306
7namespace ipmi
8{
9
Ratan Guptacc8feb42017-07-25 21:52:10 +053010using namespace phosphor::logging;
11using namespace sdbusplus::xyz::openbmc_project::Common::Error;
12
13/** @brief Gets the dbus object info implementing the given interface
14 * from the given subtree.
15 * @param[in] interface - Dbus interface.
16 * @param[in] serviceRoot - subtree from where the search should start.
17 * @param[in] match - identifier for object.
18 * @return On success returns the object having objectpath and servicename.
19 */
20
21//TODO There may be cases where an interface is implemented by multiple
22// objects,to handle such cases we are interested on that object
23// which are on interested busname.
24// Currently mapper doesn't give the readable busname(gives busid) so we can't
25// use busname to find the object,will do later once the support is there.
26
27DbusObjectInfo getDbusObject(const std::string& interface,
28 const std::string& serviceRoot,
29 const std::string& match)
30{
31 std::vector<DbusInterface> interfaces;
32 interfaces.emplace_back(interface);
33
34 auto bus = sdbusplus::bus::new_default();
35 auto depth = 0;
36
37 auto mapperCall = bus.new_method_call(MAPPER_BUS_NAME,
38 MAPPER_OBJ,
39 MAPPER_INTF,
40 "GetSubTree");
41
42 mapperCall.append(serviceRoot, depth, interfaces);
43
44 auto mapperReply = bus.call(mapperCall);
45 if (mapperReply.is_method_error())
46 {
47 log<level::ERR>("Error in mapper call");
48 elog<InternalFailure>();
49 }
50
51 ObjectTree objectTree;
52 mapperReply.read(objectTree);
53
54 if (objectTree.empty())
55 {
56 log<level::ERR>("No Object has impelmented the interface",
57 entry("INTERFACE=%s", interface.c_str()));
58 elog<InternalFailure>();
59 }
60
61 DbusObjectInfo objectInfo;
62
63 // if match is empty then return the first object
64 if(match == "")
65 {
66 objectInfo = std::make_pair(objectTree.begin()->first,
67 std::move(objectTree.begin()->second.begin()->first));
68 return objectInfo;
69 }
70
71 // else search the match string in the object path
72 auto objectFound = false;
73 for (auto& object : objectTree)
74 {
75 if(object.first.find(match) != std::string::npos)
76 {
77 objectFound = true;
78 objectInfo = make_pair(object.first,
79 std::move(object.second.begin()->first));
80 break;
81 }
82 }
83
84 if(!objectFound)
85 {
86 log<level::ERR>("Failed to find object which matches",
87 entry("MATCH=%s", match.c_str()));
88 elog<InternalFailure>();
89 }
90 return objectInfo;
91
92}
93
94/** @brief Gets the value associated with the given object
95 * and the interface.
96 * @param[in] service - Dbus service name.
97 * @param[in] objPath - Dbus object path.
98 * @param[in] interface - Dbus interface.
99 * @param[in] property - name of the property.
100 * @return On success returns the value of the property.
101 */
102Value getDbusProperty(const std::string& service,
103 const std::string& objPath,
104 const std::string& interface,
105 const std::string& property)
106{
107
108 Value value;
109
110 auto bus = sdbusplus::bus::new_default();
111
112 auto method = bus.new_method_call(
113 service.c_str(),
114 objPath.c_str(),
115 PROP_INTF,
116 METHOD_GET);
117
118 method.append(interface, property);
119
120 auto reply = bus.call(method);
121
122 if (reply.is_method_error())
123 {
124 log<level::ERR>("Failed to get property",
125 entry("PROPERTY=%s", property.c_str()),
126 entry("PATH=%s", objPath.c_str()),
127 entry("INTERFACE=%s", interface.c_str()));
128 elog<InternalFailure>();
129 }
130
131 reply.read(value);
132
133 return value;
134}
135
136/** @brief Gets all the properties associated with the given object
137 * and the interface.
138 * @param[in] service - Dbus service name.
139 * @param[in] objPath - Dbus object path.
140 * @param[in] interface - Dbus interface.
141 * @return On success returns the map of name value pair.
142 */
143PropertyMap getAllDbusProperties(const std::string& service,
144 const std::string& objPath,
145 const std::string& interface)
146{
147 PropertyMap properties;
148 auto bus = sdbusplus::bus::new_default();
149
150 auto method = bus.new_method_call(
151 service.c_str(),
152 objPath.c_str(),
153 PROP_INTF,
154 METHOD_GET_ALL);
155
156 method.append(interface);
157
158 auto reply = bus.call(method);
159
160 if (reply.is_method_error())
161 {
162 log<level::ERR>("Failed to get all properties",
163 entry("PATH=%s", objPath.c_str()),
164 entry("INTERFACE=%s", interface.c_str()));
165 elog<InternalFailure>();
166 }
167
168 reply.read(properties);
169 return properties;
170}
171
172/** @brief Sets the property value of the given object.
173 * @param[in] service - Dbus service name.
174 * @param[in] objPath - Dbus object path.
175 * @param[in] interface - Dbus interface.
176 * @param[in] property - name of the property.
177 * @param[in] value - value which needs to be set.
178 */
179void setDbusProperty(const std::string& service,
180 const std::string& objPath,
181 const std::string& interface,
182 const std::string& property,
183 const Value& value)
184{
185 auto bus = sdbusplus::bus::new_default();
186
187 auto method = bus.new_method_call(
188 service.c_str(),
189 objPath.c_str(),
190 PROP_INTF,
191 METHOD_SET);
192
193 method.append(interface, property, value);
194
195 if (!bus.call(method))
196 {
197 log<level::ERR>("Failed to set property",
198 entry("PROPERTY=%s", property.c_str()),
199 entry("PATH=%s",objPath.c_str()),
200 entry("INTERFACE=%s",interface.c_str()));
201 elog<InternalFailure>();
202 }
203
204}
205
206
Tom Josephbe703f72017-03-09 12:34:35 +0530207std::string getService(sdbusplus::bus::bus& bus,
208 const std::string& intf,
209 const std::string& path)
210{
211 auto mapperCall = bus.new_method_call("xyz.openbmc_project.ObjectMapper",
Leonel Gonzalezd15e6c92017-03-16 13:47:58 -0500212 "/xyz/openbmc_project/object_mapper",
Tom Josephbe703f72017-03-09 12:34:35 +0530213 "xyz.openbmc_project.ObjectMapper",
214 "GetObject");
215
216 mapperCall.append(path);
217 mapperCall.append(std::vector<std::string>({intf}));
218
219 auto mapperResponseMsg = bus.call(mapperCall);
220
221 if (mapperResponseMsg.is_method_error())
222 {
223 throw std::runtime_error("ERROR in mapper call");
224 }
225
226 std::map<std::string, std::vector<std::string>> mapperResponse;
227 mapperResponseMsg.read(mapperResponse);
228
229 if (mapperResponse.begin() == mapperResponse.end())
230 {
231 throw std::runtime_error("ERROR in reading the mapper response");
232 }
233
234 return mapperResponse.begin()->first;
235}
236
Ratan Guptacc8feb42017-07-25 21:52:10 +0530237
Tom Josephbe703f72017-03-09 12:34:35 +0530238} // namespace ipmi
239
240