1fa5e4d32SSunny Srivastava #pragma once
2fa5e4d32SSunny Srivastava
3fa5e4d32SSunny Srivastava #include "constants.hpp"
4c6ef42d6SSunny Srivastava #include "exceptions.hpp"
5fa5e4d32SSunny Srivastava #include "logger.hpp"
6fa5e4d32SSunny Srivastava #include "types.hpp"
7fa5e4d32SSunny Srivastava
8fa5e4d32SSunny Srivastava #include <chrono>
9fa5e4d32SSunny Srivastava
10fa5e4d32SSunny Srivastava namespace vpd
11fa5e4d32SSunny Srivastava {
12fa5e4d32SSunny Srivastava /**
13fa5e4d32SSunny Srivastava * @brief The namespace defines utlity methods for generic D-Bus operations.
14fa5e4d32SSunny Srivastava */
15fa5e4d32SSunny Srivastava namespace dbusUtility
16fa5e4d32SSunny Srivastava {
17fa5e4d32SSunny Srivastava
18fa5e4d32SSunny Srivastava /**
19fa5e4d32SSunny Srivastava * @brief An API to get Map of service and interfaces for an object path.
20fa5e4d32SSunny Srivastava *
21fa5e4d32SSunny Srivastava * The API returns a Map of service name and interfaces for a given pair of
22fa5e4d32SSunny Srivastava * object path and interface list. It can be used to determine service name
23fa5e4d32SSunny Srivastava * which implemets a particular object path and interface.
24fa5e4d32SSunny Srivastava *
25fa5e4d32SSunny Srivastava * Note: It will be caller's responsibility to check for empty map returned and
26fa5e4d32SSunny Srivastava * generate appropriate error.
27fa5e4d32SSunny Srivastava *
28fa5e4d32SSunny Srivastava * @param [in] objectPath - Object path under the service.
29fa5e4d32SSunny Srivastava * @param [in] interfaces - Array of interface(s).
30fa5e4d32SSunny Srivastava * @return - A Map of service name to object to interface(s), if success.
31fa5e4d32SSunny Srivastava * If failed, empty map.
32fa5e4d32SSunny Srivastava */
getObjectMap(const std::string & objectPath,std::span<const char * > interfaces)33fa5e4d32SSunny Srivastava inline types::MapperGetObject getObjectMap(const std::string& objectPath,
34fa5e4d32SSunny Srivastava std::span<const char*> interfaces)
35fa5e4d32SSunny Srivastava {
36fa5e4d32SSunny Srivastava types::MapperGetObject getObjectMap;
37fa5e4d32SSunny Srivastava
38fa5e4d32SSunny Srivastava // interface list is optional argument, hence no check required.
39fa5e4d32SSunny Srivastava if (objectPath.empty())
40fa5e4d32SSunny Srivastava {
41fa5e4d32SSunny Srivastava logging::logMessage("Path value is empty, invalid call to GetObject");
42fa5e4d32SSunny Srivastava return getObjectMap;
43fa5e4d32SSunny Srivastava }
44fa5e4d32SSunny Srivastava
45fa5e4d32SSunny Srivastava try
46fa5e4d32SSunny Srivastava {
47fa5e4d32SSunny Srivastava auto bus = sdbusplus::bus::new_default();
48fa5e4d32SSunny Srivastava auto method = bus.new_method_call(
49fa5e4d32SSunny Srivastava "xyz.openbmc_project.ObjectMapper",
50fa5e4d32SSunny Srivastava "/xyz/openbmc_project/object_mapper",
51fa5e4d32SSunny Srivastava "xyz.openbmc_project.ObjectMapper", "GetObject");
52fa5e4d32SSunny Srivastava
53fa5e4d32SSunny Srivastava method.append(objectPath, interfaces);
54fa5e4d32SSunny Srivastava auto result = bus.call(method);
55fa5e4d32SSunny Srivastava result.read(getObjectMap);
56fa5e4d32SSunny Srivastava }
57fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& e)
58fa5e4d32SSunny Srivastava {
59fa5e4d32SSunny Srivastava // logging::logMessage(e.what());
60fa5e4d32SSunny Srivastava return getObjectMap;
61fa5e4d32SSunny Srivastava }
62fa5e4d32SSunny Srivastava
63fa5e4d32SSunny Srivastava return getObjectMap;
64fa5e4d32SSunny Srivastava }
65fa5e4d32SSunny Srivastava
66fa5e4d32SSunny Srivastava /**
67fa5e4d32SSunny Srivastava * @brief An API to get property map for an interface.
68fa5e4d32SSunny Srivastava *
69fa5e4d32SSunny Srivastava * This API returns a map of property and its value with respect to a particular
70fa5e4d32SSunny Srivastava * interface.
71fa5e4d32SSunny Srivastava *
72fa5e4d32SSunny Srivastava * Note: It will be caller's responsibility to check for empty map returned and
73fa5e4d32SSunny Srivastava * generate appropriate error.
74fa5e4d32SSunny Srivastava *
75fa5e4d32SSunny Srivastava * @param[in] i_service - Service name.
76fa5e4d32SSunny Srivastava * @param[in] i_objectPath - object path.
77fa5e4d32SSunny Srivastava * @param[in] i_interface - Interface, for the properties to be listed.
78fa5e4d32SSunny Srivastava *
79fa5e4d32SSunny Srivastava * @return - A map of property and value of an interface, if success.
80fa5e4d32SSunny Srivastava * if failed, empty map.
81fa5e4d32SSunny Srivastava */
getPropertyMap(const std::string & i_service,const std::string & i_objectPath,const std::string & i_interface)82fa5e4d32SSunny Srivastava inline types::PropertyMap getPropertyMap(const std::string& i_service,
83fa5e4d32SSunny Srivastava const std::string& i_objectPath,
84fa5e4d32SSunny Srivastava const std::string& i_interface)
85fa5e4d32SSunny Srivastava {
86fa5e4d32SSunny Srivastava types::PropertyMap l_propertyValueMap;
87fa5e4d32SSunny Srivastava if (i_service.empty() || i_objectPath.empty() || i_interface.empty())
88fa5e4d32SSunny Srivastava {
89fa5e4d32SSunny Srivastava logging::logMessage("Invalid parameters to get property map");
90fa5e4d32SSunny Srivastava return l_propertyValueMap;
91fa5e4d32SSunny Srivastava }
92fa5e4d32SSunny Srivastava
93fa5e4d32SSunny Srivastava try
94fa5e4d32SSunny Srivastava {
95fa5e4d32SSunny Srivastava auto l_bus = sdbusplus::bus::new_default();
96fa5e4d32SSunny Srivastava auto l_method =
97fa5e4d32SSunny Srivastava l_bus.new_method_call(i_service.c_str(), i_objectPath.c_str(),
98fa5e4d32SSunny Srivastava "org.freedesktop.DBus.Properties", "GetAll");
99fa5e4d32SSunny Srivastava l_method.append(i_interface);
100fa5e4d32SSunny Srivastava auto l_result = l_bus.call(l_method);
101fa5e4d32SSunny Srivastava l_result.read(l_propertyValueMap);
102fa5e4d32SSunny Srivastava }
103fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& l_ex)
104fa5e4d32SSunny Srivastava {
105fa5e4d32SSunny Srivastava logging::logMessage(l_ex.what());
106fa5e4d32SSunny Srivastava }
107fa5e4d32SSunny Srivastava
108fa5e4d32SSunny Srivastava return l_propertyValueMap;
109fa5e4d32SSunny Srivastava }
110fa5e4d32SSunny Srivastava
111fa5e4d32SSunny Srivastava /**
112fa5e4d32SSunny Srivastava * @brief API to get object subtree from D-bus.
113fa5e4d32SSunny Srivastava *
114fa5e4d32SSunny Srivastava * The API returns the map of object, services and interfaces in the
115fa5e4d32SSunny Srivastava * subtree that implement a certain interface. If no interfaces are provided
116fa5e4d32SSunny Srivastava * then all the objects, services and interfaces under the subtree will
117fa5e4d32SSunny Srivastava * be returned.
118fa5e4d32SSunny Srivastava *
119fa5e4d32SSunny Srivastava * Note: Depth can be 0 and interfaces can be null.
120fa5e4d32SSunny Srivastava * It will be caller's responsibility to check for empty vector returned
121fa5e4d32SSunny Srivastava * and generate appropriate error.
122fa5e4d32SSunny Srivastava *
123fa5e4d32SSunny Srivastava * @param[in] i_objectPath - Path to search for an interface.
124fa5e4d32SSunny Srivastava * @param[in] i_depth - Maximum depth of the tree to search.
125fa5e4d32SSunny Srivastava * @param[in] i_interfaces - List of interfaces to search.
126fa5e4d32SSunny Srivastava *
127fa5e4d32SSunny Srivastava * @return - A map of object and its related services and interfaces, if
128fa5e4d32SSunny Srivastava * success. If failed, empty map.
129fa5e4d32SSunny Srivastava */
130fa5e4d32SSunny Srivastava
getObjectSubTree(const std::string & i_objectPath,const int & i_depth,const std::vector<std::string> & i_interfaces)13143fedabcSPatrick Williams inline types::MapperGetSubTree getObjectSubTree(
13243fedabcSPatrick Williams const std::string& i_objectPath, const int& i_depth,
133fa5e4d32SSunny Srivastava const std::vector<std::string>& i_interfaces)
134fa5e4d32SSunny Srivastava {
135fa5e4d32SSunny Srivastava types::MapperGetSubTree l_subTreeMap;
136fa5e4d32SSunny Srivastava
137fa5e4d32SSunny Srivastava if (i_objectPath.empty())
138fa5e4d32SSunny Srivastava {
139fa5e4d32SSunny Srivastava logging::logMessage("Object path is empty.");
140fa5e4d32SSunny Srivastava return l_subTreeMap;
141fa5e4d32SSunny Srivastava }
142fa5e4d32SSunny Srivastava
143fa5e4d32SSunny Srivastava try
144fa5e4d32SSunny Srivastava {
145fa5e4d32SSunny Srivastava auto l_bus = sdbusplus::bus::new_default();
146fa5e4d32SSunny Srivastava auto l_method = l_bus.new_method_call(
147fa5e4d32SSunny Srivastava constants::objectMapperService, constants::objectMapperPath,
148fa5e4d32SSunny Srivastava constants::objectMapperInf, "GetSubTree");
149fa5e4d32SSunny Srivastava l_method.append(i_objectPath, i_depth, i_interfaces);
150fa5e4d32SSunny Srivastava auto l_result = l_bus.call(l_method);
151fa5e4d32SSunny Srivastava l_result.read(l_subTreeMap);
152fa5e4d32SSunny Srivastava }
153fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& l_ex)
154fa5e4d32SSunny Srivastava {
155fa5e4d32SSunny Srivastava logging::logMessage(l_ex.what());
156fa5e4d32SSunny Srivastava }
157fa5e4d32SSunny Srivastava
158fa5e4d32SSunny Srivastava return l_subTreeMap;
159fa5e4d32SSunny Srivastava }
160fa5e4d32SSunny Srivastava
161fa5e4d32SSunny Srivastava /**
162fa5e4d32SSunny Srivastava * @brief An API to read property from Dbus.
163fa5e4d32SSunny Srivastava *
164fa5e4d32SSunny Srivastava * The caller of the API needs to validate the validatity and correctness of the
165fa5e4d32SSunny Srivastava * type and value of data returned. The API will just fetch and retun the data
166fa5e4d32SSunny Srivastava * without any data validation.
167fa5e4d32SSunny Srivastava *
168fa5e4d32SSunny Srivastava * Note: It will be caller's responsibility to check for empty value returned
169fa5e4d32SSunny Srivastava * and generate appropriate error if required.
170fa5e4d32SSunny Srivastava *
171fa5e4d32SSunny Srivastava * @param [in] serviceName - Name of the Dbus service.
172fa5e4d32SSunny Srivastava * @param [in] objectPath - Object path under the service.
173fa5e4d32SSunny Srivastava * @param [in] interface - Interface under which property exist.
174fa5e4d32SSunny Srivastava * @param [in] property - Property whose value is to be read.
175fa5e4d32SSunny Srivastava * @return - Value read from Dbus, if success.
176fa5e4d32SSunny Srivastava * If failed, empty variant.
177fa5e4d32SSunny Srivastava */
readDbusProperty(const std::string & serviceName,const std::string & objectPath,const std::string & interface,const std::string & property)178fa5e4d32SSunny Srivastava inline types::DbusVariantType readDbusProperty(
179fa5e4d32SSunny Srivastava const std::string& serviceName, const std::string& objectPath,
180fa5e4d32SSunny Srivastava const std::string& interface, const std::string& property)
181fa5e4d32SSunny Srivastava {
182fa5e4d32SSunny Srivastava types::DbusVariantType propertyValue;
183fa5e4d32SSunny Srivastava
184fa5e4d32SSunny Srivastava // Mandatory fields to make a read dbus call.
185fa5e4d32SSunny Srivastava if (serviceName.empty() || objectPath.empty() || interface.empty() ||
186fa5e4d32SSunny Srivastava property.empty())
187fa5e4d32SSunny Srivastava {
188fa5e4d32SSunny Srivastava logging::logMessage(
189fa5e4d32SSunny Srivastava "One of the parameter to make Dbus read call is empty.");
190fa5e4d32SSunny Srivastava return propertyValue;
191fa5e4d32SSunny Srivastava }
192fa5e4d32SSunny Srivastava
193fa5e4d32SSunny Srivastava try
194fa5e4d32SSunny Srivastava {
195fa5e4d32SSunny Srivastava auto bus = sdbusplus::bus::new_default();
196fa5e4d32SSunny Srivastava auto method =
197fa5e4d32SSunny Srivastava bus.new_method_call(serviceName.c_str(), objectPath.c_str(),
198fa5e4d32SSunny Srivastava "org.freedesktop.DBus.Properties", "Get");
199fa5e4d32SSunny Srivastava method.append(interface, property);
200fa5e4d32SSunny Srivastava
201fa5e4d32SSunny Srivastava auto result = bus.call(method);
202fa5e4d32SSunny Srivastava result.read(propertyValue);
203fa5e4d32SSunny Srivastava }
204fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& e)
205fa5e4d32SSunny Srivastava {
206fa5e4d32SSunny Srivastava return propertyValue;
207fa5e4d32SSunny Srivastava }
208fa5e4d32SSunny Srivastava return propertyValue;
209fa5e4d32SSunny Srivastava }
210fa5e4d32SSunny Srivastava
211fa5e4d32SSunny Srivastava /**
212fa5e4d32SSunny Srivastava * @brief An API to write property on Dbus.
213fa5e4d32SSunny Srivastava *
214fa5e4d32SSunny Srivastava * The caller of this API needs to handle exception thrown by this method to
215fa5e4d32SSunny Srivastava * identify any write failure. The API in no other way indicate write failure
216fa5e4d32SSunny Srivastava * to the caller.
217fa5e4d32SSunny Srivastava *
218fa5e4d32SSunny Srivastava * @param [in] serviceName - Name of the Dbus service.
219fa5e4d32SSunny Srivastava * @param [in] objectPath - Object path under the service.
220fa5e4d32SSunny Srivastava * @param [in] interface - Interface under which property exist.
221fa5e4d32SSunny Srivastava * @param [in] property - Property whose value is to be written.
222fa5e4d32SSunny Srivastava * @param [in] propertyValue - The value to be written.
223c532b188SRekhaAparna01 * @return True if write on DBus is success, false otherwise.
224fa5e4d32SSunny Srivastava */
writeDbusProperty(const std::string & serviceName,const std::string & objectPath,const std::string & interface,const std::string & property,const types::DbusVariantType & propertyValue)225c532b188SRekhaAparna01 inline bool writeDbusProperty(
226fa5e4d32SSunny Srivastava const std::string& serviceName, const std::string& objectPath,
227fa5e4d32SSunny Srivastava const std::string& interface, const std::string& property,
228fa5e4d32SSunny Srivastava const types::DbusVariantType& propertyValue)
229fa5e4d32SSunny Srivastava {
230c532b188SRekhaAparna01 try
231c532b188SRekhaAparna01 {
232fa5e4d32SSunny Srivastava // Mandatory fields to make a write dbus call.
233fa5e4d32SSunny Srivastava if (serviceName.empty() || objectPath.empty() || interface.empty() ||
234fa5e4d32SSunny Srivastava property.empty())
235fa5e4d32SSunny Srivastava {
236fa5e4d32SSunny Srivastava throw std::runtime_error("Dbus write failed, Parameter empty");
237fa5e4d32SSunny Srivastava }
238fa5e4d32SSunny Srivastava
239fa5e4d32SSunny Srivastava auto bus = sdbusplus::bus::new_default();
240fa5e4d32SSunny Srivastava auto method =
241fa5e4d32SSunny Srivastava bus.new_method_call(serviceName.c_str(), objectPath.c_str(),
242fa5e4d32SSunny Srivastava "org.freedesktop.DBus.Properties", "Set");
243fa5e4d32SSunny Srivastava method.append(interface, property, propertyValue);
244fa5e4d32SSunny Srivastava bus.call(method);
245fa5e4d32SSunny Srivastava
246c532b188SRekhaAparna01 return true;
247c532b188SRekhaAparna01 }
248c532b188SRekhaAparna01 catch (const std::exception& l_ex)
249c532b188SRekhaAparna01 {
250c532b188SRekhaAparna01 logging::logMessage(
251c532b188SRekhaAparna01 "DBus write failed, error: " + std::string(l_ex.what()));
252c532b188SRekhaAparna01 return false;
253fa5e4d32SSunny Srivastava }
254fa5e4d32SSunny Srivastava }
255fa5e4d32SSunny Srivastava
256fa5e4d32SSunny Srivastava /**
257fa5e4d32SSunny Srivastava * @brief API to publish data on PIM
258fa5e4d32SSunny Srivastava *
259fa5e4d32SSunny Srivastava * The API calls notify on PIM object to publlish VPD.
260fa5e4d32SSunny Srivastava *
261fa5e4d32SSunny Srivastava * @param[in] objectMap - Object, its interface and data.
262fa5e4d32SSunny Srivastava * @return bool - Status of call to PIM notify.
263fa5e4d32SSunny Srivastava */
callPIM(types::ObjectMap && objectMap)264fa5e4d32SSunny Srivastava inline bool callPIM(types::ObjectMap&& objectMap)
265fa5e4d32SSunny Srivastava {
266fa5e4d32SSunny Srivastava try
267fa5e4d32SSunny Srivastava {
268fa5e4d32SSunny Srivastava for (const auto& l_objectKeyValue : objectMap)
269fa5e4d32SSunny Srivastava {
270fa5e4d32SSunny Srivastava auto l_nodeHandle = objectMap.extract(l_objectKeyValue.first);
271fa5e4d32SSunny Srivastava
272fa5e4d32SSunny Srivastava if (l_nodeHandle.key().str.find(constants::pimPath, 0) !=
273fa5e4d32SSunny Srivastava std::string::npos)
274fa5e4d32SSunny Srivastava {
275fa5e4d32SSunny Srivastava l_nodeHandle.key() = l_nodeHandle.key().str.replace(
276fa5e4d32SSunny Srivastava 0, std::strlen(constants::pimPath), "");
277fa5e4d32SSunny Srivastava objectMap.insert(std::move(l_nodeHandle));
278fa5e4d32SSunny Srivastava }
279fa5e4d32SSunny Srivastava }
280fa5e4d32SSunny Srivastava
281fa5e4d32SSunny Srivastava auto bus = sdbusplus::bus::new_default();
282fa5e4d32SSunny Srivastava auto pimMsg =
283fa5e4d32SSunny Srivastava bus.new_method_call(constants::pimServiceName, constants::pimPath,
284fa5e4d32SSunny Srivastava constants::pimIntf, "Notify");
285fa5e4d32SSunny Srivastava pimMsg.append(std::move(objectMap));
286fa5e4d32SSunny Srivastava bus.call(pimMsg);
287fa5e4d32SSunny Srivastava }
288fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& e)
289fa5e4d32SSunny Srivastava {
290fa5e4d32SSunny Srivastava return false;
291fa5e4d32SSunny Srivastava }
292fa5e4d32SSunny Srivastava return true;
293fa5e4d32SSunny Srivastava }
294fa5e4d32SSunny Srivastava
295fa5e4d32SSunny Srivastava /**
296fa5e4d32SSunny Srivastava * @brief API to check if a D-Bus service is running or not.
297fa5e4d32SSunny Srivastava *
298fa5e4d32SSunny Srivastava * Any failure in calling the method "NameHasOwner" implies that the service is
299fa5e4d32SSunny Srivastava * not in a running state. Hence the API returns false in case of any exception
300fa5e4d32SSunny Srivastava * as well.
301fa5e4d32SSunny Srivastava *
302fa5e4d32SSunny Srivastava * @param[in] i_serviceName - D-Bus service name whose status is to be checked.
303fa5e4d32SSunny Srivastava * @return bool - True if the service is running, false otherwise.
304fa5e4d32SSunny Srivastava */
isServiceRunning(const std::string & i_serviceName)305fa5e4d32SSunny Srivastava inline bool isServiceRunning(const std::string& i_serviceName)
306fa5e4d32SSunny Srivastava {
307fa5e4d32SSunny Srivastava bool l_retVal = false;
308fa5e4d32SSunny Srivastava
309fa5e4d32SSunny Srivastava try
310fa5e4d32SSunny Srivastava {
311fa5e4d32SSunny Srivastava auto l_bus = sdbusplus::bus::new_default();
312fa5e4d32SSunny Srivastava auto l_method = l_bus.new_method_call(
313fa5e4d32SSunny Srivastava "org.freedesktop.DBus", "/org/freedesktop/DBus",
314fa5e4d32SSunny Srivastava "org.freedesktop.DBus", "NameHasOwner");
315fa5e4d32SSunny Srivastava l_method.append(i_serviceName);
316fa5e4d32SSunny Srivastava
317fa5e4d32SSunny Srivastava l_bus.call(l_method).read(l_retVal);
318fa5e4d32SSunny Srivastava }
319fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& l_ex)
320fa5e4d32SSunny Srivastava {
321fa5e4d32SSunny Srivastava logging::logMessage(
322fa5e4d32SSunny Srivastava "Call to check service status failed with exception: " +
323fa5e4d32SSunny Srivastava std::string(l_ex.what()));
324fa5e4d32SSunny Srivastava }
325fa5e4d32SSunny Srivastava
326fa5e4d32SSunny Srivastava return l_retVal;
327fa5e4d32SSunny Srivastava }
328fa5e4d32SSunny Srivastava
329fa5e4d32SSunny Srivastava /**
330fa5e4d32SSunny Srivastava * @brief API to call "GetAttribute" method uner BIOS manager.
331fa5e4d32SSunny Srivastava *
332fa5e4d32SSunny Srivastava * The API reads the given attribuute from BIOS and returns a tuple of both
333fa5e4d32SSunny Srivastava * current as well as pending value for that attribute.
334fa5e4d32SSunny Srivastava * The API return only the current attribute value if found.
335fa5e4d32SSunny Srivastava * API returns an empty variant of type BiosAttributeCurrentValue in case of any
336fa5e4d32SSunny Srivastava * error.
337fa5e4d32SSunny Srivastava *
338fa5e4d32SSunny Srivastava * @param[in] i_attributeName - Attribute to be read.
339fa5e4d32SSunny Srivastava * @return Tuple of PLDM attribute Type, current attribute value and pending
340fa5e4d32SSunny Srivastava * attribute value.
341fa5e4d32SSunny Srivastava */
biosGetAttributeMethodCall(const std::string & i_attributeName)34243fedabcSPatrick Williams inline types::BiosAttributeCurrentValue biosGetAttributeMethodCall(
34343fedabcSPatrick Williams const std::string& i_attributeName)
344fa5e4d32SSunny Srivastava {
345fa5e4d32SSunny Srivastava auto l_bus = sdbusplus::bus::new_default();
346fa5e4d32SSunny Srivastava auto l_method = l_bus.new_method_call(
347fa5e4d32SSunny Srivastava constants::biosConfigMgrService, constants::biosConfigMgrObjPath,
348fa5e4d32SSunny Srivastava constants::biosConfigMgrInterface, "GetAttribute");
349fa5e4d32SSunny Srivastava l_method.append(i_attributeName);
350fa5e4d32SSunny Srivastava
351fa5e4d32SSunny Srivastava types::BiosGetAttrRetType l_attributeVal;
352fa5e4d32SSunny Srivastava try
353fa5e4d32SSunny Srivastava {
354fa5e4d32SSunny Srivastava auto l_result = l_bus.call(l_method);
355fa5e4d32SSunny Srivastava l_result.read(std::get<0>(l_attributeVal), std::get<1>(l_attributeVal),
356fa5e4d32SSunny Srivastava std::get<2>(l_attributeVal));
357fa5e4d32SSunny Srivastava }
358fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& l_ex)
359fa5e4d32SSunny Srivastava {
360fa5e4d32SSunny Srivastava logging::logMessage(
361fa5e4d32SSunny Srivastava "Failed to read BIOS Attribute: " + i_attributeName +
362fa5e4d32SSunny Srivastava " due to error " + std::string(l_ex.what()));
363fa5e4d32SSunny Srivastava
364fa5e4d32SSunny Srivastava // TODO: Log an informational PEL here.
365fa5e4d32SSunny Srivastava }
366fa5e4d32SSunny Srivastava
367fa5e4d32SSunny Srivastava return std::get<1>(l_attributeVal);
368fa5e4d32SSunny Srivastava }
369fa5e4d32SSunny Srivastava
370fa5e4d32SSunny Srivastava /**
371fa5e4d32SSunny Srivastava * @brief API to check if Chassis is powered on.
372fa5e4d32SSunny Srivastava *
373fa5e4d32SSunny Srivastava * This API queries Phosphor Chassis State Manager to know whether
374fa5e4d32SSunny Srivastava * Chassis is powered on.
375fa5e4d32SSunny Srivastava *
376fa5e4d32SSunny Srivastava * @return true if chassis is powered on, false otherwise
377fa5e4d32SSunny Srivastava */
isChassisPowerOn()378fa5e4d32SSunny Srivastava inline bool isChassisPowerOn()
379fa5e4d32SSunny Srivastava {
380fa5e4d32SSunny Srivastava auto powerState = dbusUtility::readDbusProperty(
381fa5e4d32SSunny Srivastava "xyz.openbmc_project.State.Chassis",
382fa5e4d32SSunny Srivastava "/xyz/openbmc_project/state/chassis0",
383fa5e4d32SSunny Srivastava "xyz.openbmc_project.State.Chassis", "CurrentPowerState");
384fa5e4d32SSunny Srivastava
385fa5e4d32SSunny Srivastava if (auto curPowerState = std::get_if<std::string>(&powerState))
386fa5e4d32SSunny Srivastava {
387fa5e4d32SSunny Srivastava if ("xyz.openbmc_project.State.Chassis.PowerState.On" == *curPowerState)
388fa5e4d32SSunny Srivastava {
389fa5e4d32SSunny Srivastava return true;
390fa5e4d32SSunny Srivastava }
391fa5e4d32SSunny Srivastava return false;
392fa5e4d32SSunny Srivastava }
393fa5e4d32SSunny Srivastava
394fa5e4d32SSunny Srivastava /*
395fa5e4d32SSunny Srivastava TODO: Add PEL.
396fa5e4d32SSunny Srivastava Callout: Firmware callout
397fa5e4d32SSunny Srivastava Type: Informational
398fa5e4d32SSunny Srivastava Description: Chassis state can't be determined, defaulting to chassis
399fa5e4d32SSunny Srivastava off. : e.what()
400fa5e4d32SSunny Srivastava */
401fa5e4d32SSunny Srivastava return false;
402fa5e4d32SSunny Srivastava }
403fa5e4d32SSunny Srivastava
404fa5e4d32SSunny Srivastava /**
405fa5e4d32SSunny Srivastava * @brief API to check if host is in running state.
406fa5e4d32SSunny Srivastava *
407fa5e4d32SSunny Srivastava * This API reads the current host state from D-bus and returns true if the host
408fa5e4d32SSunny Srivastava * is running.
409fa5e4d32SSunny Srivastava *
410fa5e4d32SSunny Srivastava * @return true if host is in running state. false otherwise.
411fa5e4d32SSunny Srivastava */
isHostRunning()412fa5e4d32SSunny Srivastava inline bool isHostRunning()
413fa5e4d32SSunny Srivastava {
414fa5e4d32SSunny Srivastava const auto l_hostState = dbusUtility::readDbusProperty(
415fa5e4d32SSunny Srivastava constants::hostService, constants::hostObjectPath,
416fa5e4d32SSunny Srivastava constants::hostInterface, "CurrentHostState");
417fa5e4d32SSunny Srivastava
418fa5e4d32SSunny Srivastava if (const auto l_currHostState = std::get_if<std::string>(&l_hostState))
419fa5e4d32SSunny Srivastava {
420fa5e4d32SSunny Srivastava if (*l_currHostState == constants::hostRunningState)
421fa5e4d32SSunny Srivastava {
422fa5e4d32SSunny Srivastava return true;
423fa5e4d32SSunny Srivastava }
424fa5e4d32SSunny Srivastava }
425fa5e4d32SSunny Srivastava
426fa5e4d32SSunny Srivastava return false;
427fa5e4d32SSunny Srivastava }
428fa5e4d32SSunny Srivastava
429fa5e4d32SSunny Srivastava /**
430fa5e4d32SSunny Srivastava * @brief API to check if BMC is in ready state.
431fa5e4d32SSunny Srivastava *
432fa5e4d32SSunny Srivastava * This API reads the current state of BMC from D-bus and returns true if BMC is
433fa5e4d32SSunny Srivastava * in ready state.
434fa5e4d32SSunny Srivastava *
435fa5e4d32SSunny Srivastava * @return true if BMC is ready, false otherwise.
436fa5e4d32SSunny Srivastava */
isBMCReady()437fa5e4d32SSunny Srivastava inline bool isBMCReady()
438fa5e4d32SSunny Srivastava {
439fa5e4d32SSunny Srivastava const auto l_bmcState = dbusUtility::readDbusProperty(
440fa5e4d32SSunny Srivastava constants::bmcStateService, constants::bmcZeroStateObject,
441fa5e4d32SSunny Srivastava constants::bmcStateInterface, constants::currentBMCStateProperty);
442fa5e4d32SSunny Srivastava
443fa5e4d32SSunny Srivastava if (const auto l_currBMCState = std::get_if<std::string>(&l_bmcState))
444fa5e4d32SSunny Srivastava {
445fa5e4d32SSunny Srivastava if (*l_currBMCState == constants::bmcReadyState)
446fa5e4d32SSunny Srivastava {
447fa5e4d32SSunny Srivastava return true;
448fa5e4d32SSunny Srivastava }
449fa5e4d32SSunny Srivastava }
450fa5e4d32SSunny Srivastava
451fa5e4d32SSunny Srivastava return false;
452fa5e4d32SSunny Srivastava }
453fa5e4d32SSunny Srivastava
454fa5e4d32SSunny Srivastava /**
455fa5e4d32SSunny Srivastava * @brief An API to enable BMC reboot guard
456fa5e4d32SSunny Srivastava *
457fa5e4d32SSunny Srivastava * This API does a D-Bus method call to enable BMC reboot guard.
458fa5e4d32SSunny Srivastava *
459fa5e4d32SSunny Srivastava * @return On success, returns 0, otherwise returns -1.
460fa5e4d32SSunny Srivastava */
EnableRebootGuard()461fa5e4d32SSunny Srivastava inline int EnableRebootGuard() noexcept
462fa5e4d32SSunny Srivastava {
463fa5e4d32SSunny Srivastava int l_rc{constants::FAILURE};
464fa5e4d32SSunny Srivastava try
465fa5e4d32SSunny Srivastava {
466fa5e4d32SSunny Srivastava auto l_bus = sdbusplus::bus::new_default();
467fa5e4d32SSunny Srivastava auto l_method = l_bus.new_method_call(
468fa5e4d32SSunny Srivastava constants::systemdService, constants::systemdObjectPath,
469fa5e4d32SSunny Srivastava constants::systemdManagerInterface, "StartUnit");
470fa5e4d32SSunny Srivastava l_method.append("reboot-guard-enable.service", "replace");
471fa5e4d32SSunny Srivastava l_bus.call_noreply(l_method);
472fa5e4d32SSunny Srivastava l_rc = constants::SUCCESS;
473fa5e4d32SSunny Srivastava }
474fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& l_ex)
475fa5e4d32SSunny Srivastava {
476fa5e4d32SSunny Srivastava std::string l_errMsg =
477fa5e4d32SSunny Srivastava "D-Bus call to enable BMC reboot guard failed for reason: ";
478fa5e4d32SSunny Srivastava l_errMsg += l_ex.what();
479fa5e4d32SSunny Srivastava
480fa5e4d32SSunny Srivastava logging::logMessage(l_errMsg);
481fa5e4d32SSunny Srivastava }
482fa5e4d32SSunny Srivastava return l_rc;
483fa5e4d32SSunny Srivastava }
484fa5e4d32SSunny Srivastava
485fa5e4d32SSunny Srivastava /**
486fa5e4d32SSunny Srivastava * @brief An API to disable BMC reboot guard
487fa5e4d32SSunny Srivastava *
488fa5e4d32SSunny Srivastava * This API disables BMC reboot guard. This API has an inbuilt re-try mechanism.
489fa5e4d32SSunny Srivastava * If Disable Reboot Guard fails, this API attempts to Disable Reboot Guard for
490fa5e4d32SSunny Srivastava * 3 more times at an interval of 333ms.
491fa5e4d32SSunny Srivastava *
492fa5e4d32SSunny Srivastava * @return On success, returns 0, otherwise returns -1.
493fa5e4d32SSunny Srivastava */
DisableRebootGuard()494fa5e4d32SSunny Srivastava inline int DisableRebootGuard() noexcept
495fa5e4d32SSunny Srivastava {
496fa5e4d32SSunny Srivastava int l_rc{constants::FAILURE};
497fa5e4d32SSunny Srivastava
498fa5e4d32SSunny Srivastava // A lambda which executes the DBus call to disable BMC reboot guard.
499fa5e4d32SSunny Srivastava auto l_executeDisableRebootGuard = []() -> int {
500fa5e4d32SSunny Srivastava int l_dBusCallRc{constants::FAILURE};
501fa5e4d32SSunny Srivastava try
502fa5e4d32SSunny Srivastava {
503fa5e4d32SSunny Srivastava auto l_bus = sdbusplus::bus::new_default();
504fa5e4d32SSunny Srivastava auto l_method = l_bus.new_method_call(
505fa5e4d32SSunny Srivastava constants::systemdService, constants::systemdObjectPath,
506fa5e4d32SSunny Srivastava constants::systemdManagerInterface, "StartUnit");
507fa5e4d32SSunny Srivastava l_method.append("reboot-guard-disable.service", "replace");
508fa5e4d32SSunny Srivastava l_bus.call_noreply(l_method);
509fa5e4d32SSunny Srivastava l_dBusCallRc = constants::SUCCESS;
510fa5e4d32SSunny Srivastava }
511fa5e4d32SSunny Srivastava catch (const sdbusplus::exception::SdBusError& l_ex)
512fa5e4d32SSunny Srivastava {}
513fa5e4d32SSunny Srivastava return l_dBusCallRc;
514fa5e4d32SSunny Srivastava };
515fa5e4d32SSunny Srivastava
516fa5e4d32SSunny Srivastava if (constants::FAILURE == l_executeDisableRebootGuard())
517fa5e4d32SSunny Srivastava {
518fa5e4d32SSunny Srivastava std::function<void()> l_retryDisableRebootGuard;
519fa5e4d32SSunny Srivastava
520fa5e4d32SSunny Srivastava // A lambda which tries to disable BMC reboot guard for 3 times at an
521fa5e4d32SSunny Srivastava // interval of 333 ms.
522fa5e4d32SSunny Srivastava l_retryDisableRebootGuard = [&]() {
523fa5e4d32SSunny Srivastava constexpr int MAX_RETRIES{3};
524fa5e4d32SSunny Srivastava static int l_numRetries{0};
525fa5e4d32SSunny Srivastava
526fa5e4d32SSunny Srivastava if (l_numRetries < MAX_RETRIES)
527fa5e4d32SSunny Srivastava {
528fa5e4d32SSunny Srivastava l_numRetries++;
529fa5e4d32SSunny Srivastava if (constants::FAILURE == l_executeDisableRebootGuard())
530fa5e4d32SSunny Srivastava {
531fa5e4d32SSunny Srivastava // sleep for 333ms before next retry. This is just a random
532fa5e4d32SSunny Srivastava // value so that 3 re-tries * 333ms takes ~1 second in the
533fa5e4d32SSunny Srivastava // worst case.
534fa5e4d32SSunny Srivastava const std::chrono::milliseconds l_sleepTime{333};
535fa5e4d32SSunny Srivastava std::this_thread::sleep_for(l_sleepTime);
536fa5e4d32SSunny Srivastava l_retryDisableRebootGuard();
537fa5e4d32SSunny Srivastava }
538fa5e4d32SSunny Srivastava else
539fa5e4d32SSunny Srivastava {
540fa5e4d32SSunny Srivastava l_numRetries = 0;
541fa5e4d32SSunny Srivastava l_rc = constants::SUCCESS;
542fa5e4d32SSunny Srivastava }
543fa5e4d32SSunny Srivastava }
544fa5e4d32SSunny Srivastava else
545fa5e4d32SSunny Srivastava {
546fa5e4d32SSunny Srivastava // Failed to Disable Reboot Guard even after 3 retries.
547fa5e4d32SSunny Srivastava logging::logMessage("Failed to Disable Reboot Guard after " +
548fa5e4d32SSunny Srivastava std::to_string(MAX_RETRIES) + " re-tries");
549fa5e4d32SSunny Srivastava l_numRetries = 0;
550fa5e4d32SSunny Srivastava }
551fa5e4d32SSunny Srivastava };
552fa5e4d32SSunny Srivastava
553fa5e4d32SSunny Srivastava l_retryDisableRebootGuard();
554fa5e4d32SSunny Srivastava }
555fa5e4d32SSunny Srivastava else
556fa5e4d32SSunny Srivastava {
557fa5e4d32SSunny Srivastava l_rc = constants::SUCCESS;
558fa5e4d32SSunny Srivastava }
559fa5e4d32SSunny Srivastava return l_rc;
560fa5e4d32SSunny Srivastava }
561fa5e4d32SSunny Srivastava
5621aad7834SPriyanga Ramasamy /**
5631aad7834SPriyanga Ramasamy * @brief API to notify FRU VPD Collection status.
5641aad7834SPriyanga Ramasamy *
5651aad7834SPriyanga Ramasamy * This API uses PIM's Notify method to update the given FRU VPD collection
5661aad7834SPriyanga Ramasamy * status on D-bus.
5671aad7834SPriyanga Ramasamy *
5681aad7834SPriyanga Ramasamy * @param[in] i_inventoryPath - D-bus inventory path
5691aad7834SPriyanga Ramasamy * @param[in] i_fruCollectionStatus - FRU VPD collection status.
5701aad7834SPriyanga Ramasamy *
5711aad7834SPriyanga Ramasamy * @return true if update succeeds, false otherwise.
5721aad7834SPriyanga Ramasamy */
notifyFRUCollectionStatus(const std::string & i_inventoryPath,const std::string & i_fruCollectionStatus)5731aad7834SPriyanga Ramasamy inline bool notifyFRUCollectionStatus(const std::string& i_inventoryPath,
5741aad7834SPriyanga Ramasamy const std::string& i_fruCollectionStatus)
5751aad7834SPriyanga Ramasamy {
5761aad7834SPriyanga Ramasamy types::ObjectMap l_objectMap;
5771aad7834SPriyanga Ramasamy types::InterfaceMap l_interfaceMap;
5781aad7834SPriyanga Ramasamy types::PropertyMap l_propertyMap;
5791aad7834SPriyanga Ramasamy
5801aad7834SPriyanga Ramasamy l_propertyMap.emplace("CollectionStatus", i_fruCollectionStatus);
5811aad7834SPriyanga Ramasamy l_interfaceMap.emplace(constants::vpdCollectionInterface, l_propertyMap);
5821aad7834SPriyanga Ramasamy l_objectMap.emplace(i_inventoryPath, l_interfaceMap);
5831aad7834SPriyanga Ramasamy
5841aad7834SPriyanga Ramasamy if (!dbusUtility::callPIM(std::move(l_objectMap)))
5851aad7834SPriyanga Ramasamy {
5861aad7834SPriyanga Ramasamy return false;
5871aad7834SPriyanga Ramasamy }
5881aad7834SPriyanga Ramasamy
5891aad7834SPriyanga Ramasamy return true;
5901aad7834SPriyanga Ramasamy }
5911a48f0ceSSunny Srivastava
5921a48f0ceSSunny Srivastava /**
5931a48f0ceSSunny Srivastava * @brief API to read IM keyword from Dbus.
5941a48f0ceSSunny Srivastava *
5951a48f0ceSSunny Srivastava * @return IM value read from Dbus, Empty in case of any error.
5961a48f0ceSSunny Srivastava */
getImFromDbus()5971a48f0ceSSunny Srivastava inline types::BinaryVector getImFromDbus()
5981a48f0ceSSunny Srivastava {
5991a48f0ceSSunny Srivastava const auto& l_retValue = dbusUtility::readDbusProperty(
6001a48f0ceSSunny Srivastava constants::pimServiceName, constants::systemVpdInvPath,
6011a48f0ceSSunny Srivastava constants::vsbpInf, constants::kwdIM);
6021a48f0ceSSunny Srivastava
6031a48f0ceSSunny Srivastava auto l_imValue = std::get_if<types::BinaryVector>(&l_retValue);
6041a48f0ceSSunny Srivastava if (!l_imValue || (*l_imValue).size() != constants::VALUE_4)
6051a48f0ceSSunny Srivastava {
6061a48f0ceSSunny Srivastava return types::BinaryVector{};
6071a48f0ceSSunny Srivastava }
6081a48f0ceSSunny Srivastava
6091a48f0ceSSunny Srivastava return *l_imValue;
6101a48f0ceSSunny Srivastava }
611c6ef42d6SSunny Srivastava
612c6ef42d6SSunny Srivastava /**
613c6ef42d6SSunny Srivastava * @brief API to return prefix of functional firmware image.
614c6ef42d6SSunny Srivastava *
615c6ef42d6SSunny Srivastava * Every functional image belongs to a series which is denoted by the first two
616c6ef42d6SSunny Srivastava * characters of the image name. The API extracts that and returns it to the
617c6ef42d6SSunny Srivastava * caller.
618c6ef42d6SSunny Srivastava *
619c6ef42d6SSunny Srivastava * @return Two character string, empty string in case of any error.
620c6ef42d6SSunny Srivastava */
getImagePrefix()621c6ef42d6SSunny Srivastava inline std::string getImagePrefix()
622c6ef42d6SSunny Srivastava {
623c6ef42d6SSunny Srivastava try
624c6ef42d6SSunny Srivastava {
625c6ef42d6SSunny Srivastava types::DbusVariantType l_retVal = readDbusProperty(
626c6ef42d6SSunny Srivastava constants::objectMapperService, constants::functionalImageObjPath,
627c6ef42d6SSunny Srivastava constants::associationInterface, "endpoints");
628c6ef42d6SSunny Srivastava
629c6ef42d6SSunny Srivastava auto l_listOfFunctionalPath =
630c6ef42d6SSunny Srivastava std::get_if<std::vector<std::string>>(&l_retVal);
631c6ef42d6SSunny Srivastava
632c6ef42d6SSunny Srivastava if (!l_listOfFunctionalPath || (*l_listOfFunctionalPath).empty())
633c6ef42d6SSunny Srivastava {
634c6ef42d6SSunny Srivastava throw DbusException("failed to get functional image path.");
635c6ef42d6SSunny Srivastava }
636c6ef42d6SSunny Srivastava
637c6ef42d6SSunny Srivastava for (const auto& l_imagePath : *l_listOfFunctionalPath)
638c6ef42d6SSunny Srivastava {
639c6ef42d6SSunny Srivastava types::DbusVariantType l_retValPriority =
640c6ef42d6SSunny Srivastava readDbusProperty(constants::imageUpdateService, l_imagePath,
641c6ef42d6SSunny Srivastava constants::imagePrirotyInf, "Priority");
642c6ef42d6SSunny Srivastava
643c6ef42d6SSunny Srivastava auto l_imagePriority = std::get_if<uint8_t>(&l_retValPriority);
644c6ef42d6SSunny Srivastava if (!l_imagePriority)
645c6ef42d6SSunny Srivastava {
646c6ef42d6SSunny Srivastava throw DbusException(
647c6ef42d6SSunny Srivastava "failed to read functional image priority for path [" +
648c6ef42d6SSunny Srivastava l_imagePath + "]");
649c6ef42d6SSunny Srivastava }
650c6ef42d6SSunny Srivastava
651c6ef42d6SSunny Srivastava // only interested in running image.
652c6ef42d6SSunny Srivastava if (*l_imagePriority != constants::VALUE_0)
653c6ef42d6SSunny Srivastava {
654c6ef42d6SSunny Srivastava continue;
655c6ef42d6SSunny Srivastava }
656c6ef42d6SSunny Srivastava
657c6ef42d6SSunny Srivastava types::DbusVariantType l_retExVer = readDbusProperty(
658c6ef42d6SSunny Srivastava constants::imageUpdateService, l_imagePath,
659c6ef42d6SSunny Srivastava constants::imageExtendedVerInf, "ExtendedVersion");
660c6ef42d6SSunny Srivastava
661c6ef42d6SSunny Srivastava auto l_imageExtendedVersion = std::get_if<std::string>(&l_retExVer);
662c6ef42d6SSunny Srivastava if (!l_imageExtendedVersion)
663c6ef42d6SSunny Srivastava {
664c6ef42d6SSunny Srivastava throw DbusException(
665c6ef42d6SSunny Srivastava "Unable to read extended version for the functional image [" +
666c6ef42d6SSunny Srivastava l_imagePath + "]");
667c6ef42d6SSunny Srivastava }
668c6ef42d6SSunny Srivastava
669c6ef42d6SSunny Srivastava if ((*l_imageExtendedVersion).empty() ||
670c6ef42d6SSunny Srivastava (*l_imageExtendedVersion).length() <= constants::VALUE_2)
671c6ef42d6SSunny Srivastava {
672c6ef42d6SSunny Srivastava throw DbusException("Invalid extended version read for path [" +
673c6ef42d6SSunny Srivastava l_imagePath + "]");
674c6ef42d6SSunny Srivastava }
675c6ef42d6SSunny Srivastava
676c6ef42d6SSunny Srivastava // return first two character from image name.
677c6ef42d6SSunny Srivastava return (*l_imageExtendedVersion)
678c6ef42d6SSunny Srivastava .substr(constants::VALUE_0, constants::VALUE_2);
679c6ef42d6SSunny Srivastava }
680c6ef42d6SSunny Srivastava throw std::runtime_error("No Image found with required priority.");
681c6ef42d6SSunny Srivastava }
682c6ef42d6SSunny Srivastava catch (const std::exception& l_ex)
683c6ef42d6SSunny Srivastava {
684c6ef42d6SSunny Srivastava logging::logMessage(l_ex.what());
685c6ef42d6SSunny Srivastava return std::string{};
686c6ef42d6SSunny Srivastava }
687c6ef42d6SSunny Srivastava }
688*f1dda767SSunny Srivastava
689*f1dda767SSunny Srivastava /**
690*f1dda767SSunny Srivastava * @brief API to read DBus present property for the given inventory.
691*f1dda767SSunny Srivastava *
692*f1dda767SSunny Srivastava * @param[in] i_invObjPath - Inventory path.
693*f1dda767SSunny Srivastava * @return Present property value, false in case of any error.
694*f1dda767SSunny Srivastava */
isInventoryPresent(const std::string & i_invObjPath)695*f1dda767SSunny Srivastava inline bool isInventoryPresent(const std::string& i_invObjPath)
696*f1dda767SSunny Srivastava {
697*f1dda767SSunny Srivastava if (i_invObjPath.empty())
698*f1dda767SSunny Srivastava {
699*f1dda767SSunny Srivastava return false;
700*f1dda767SSunny Srivastava }
701*f1dda767SSunny Srivastava
702*f1dda767SSunny Srivastava const auto& l_retValue =
703*f1dda767SSunny Srivastava dbusUtility::readDbusProperty(constants::pimServiceName, i_invObjPath,
704*f1dda767SSunny Srivastava constants::inventoryItemInf, "Present");
705*f1dda767SSunny Srivastava
706*f1dda767SSunny Srivastava auto l_ptrPresence = std::get_if<bool>(&l_retValue);
707*f1dda767SSunny Srivastava if (!l_ptrPresence)
708*f1dda767SSunny Srivastava {
709*f1dda767SSunny Srivastava return false;
710*f1dda767SSunny Srivastava }
711*f1dda767SSunny Srivastava
712*f1dda767SSunny Srivastava return (*l_ptrPresence);
713*f1dda767SSunny Srivastava }
714fa5e4d32SSunny Srivastava } // namespace dbusUtility
715fa5e4d32SSunny Srivastava } // namespace vpd
716