xref: /openbmc/openpower-vpd-parser/vpd-manager/include/utility/dbus_utility.hpp (revision f1dda76723edde8dfc9fe65f6ceff7bc89227879)
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