blob: fafd646be71e32d64fddb957049222567572f781 [file] [log] [blame]
#pragma once
#include <sdbusplus/bus.hpp>
#include <experimental/any>
#include <string>
#include <vector>
namespace utils
{
class UtilsInterface;
// Due to a libstdc++ bug, we got compile error using std::any with gmock.
// A temporary workaround is to use std::experimental::any.
// See details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415
using std::experimental::any;
using std::experimental::any_cast;
using ValueType =
std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
uint64_t, double, std::string>;
/**
* @brief Get the implementation of UtilsInterface
*/
const UtilsInterface& getUtils();
/** @brief Get service name from object path and interface
*
* @param[in] bus - The Dbus bus object
* @param[in] path - The Dbus object path
* @param[in] interface - The Dbus interface
*
* @return The name of the service
*/
std::string getService(sdbusplus::bus::bus& bus, const char* path,
const char* interface);
/** @brief Get all the service names from object path and interface
*
* @param[in] bus - The Dbus bus object
* @param[in] path - The Dbus object path
* @param[in] interface - The Dbus interface
*
* @return The name of the services
*/
std::vector<std::string> getServices(sdbusplus::bus::bus& bus, const char* path,
const char* interface);
/** @brief The template function to get property from the requested dbus path
*
* @param[in] bus - The Dbus bus object
* @param[in] service - The Dbus service name
* @param[in] path - The Dbus object path
* @param[in] interface - The Dbus interface
* @param[in] propertyName - The property name to get
*
* @return The value of the property
*/
template <typename T>
T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
const char* interface, const char* propertyName);
template <typename T>
void setProperty(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName, const T& value);
/**
* @brief The interface for utils
*/
class UtilsInterface
{
public:
// For now the code needs to get property for Present and Version
using PropertyType = std::variant<std::string, bool>;
virtual ~UtilsInterface() = default;
virtual std::string getService(sdbusplus::bus::bus& bus, const char* path,
const char* interface) const = 0;
virtual std::vector<std::string>
getServices(sdbusplus::bus::bus& bus, const char* path,
const char* interface) const = 0;
virtual any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName) const = 0;
virtual void setPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName,
ValueType&& value) const = 0;
template <typename T>
T getProperty(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName) const
{
any result =
getPropertyImpl(bus, service, path, interface, propertyName);
auto value = any_cast<PropertyType>(result);
return std::get<T>(value);
}
template <typename T>
void setProperty(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName, const T& value) const
{
ValueType v(value);
setPropertyImpl(bus, service, path, interface, propertyName,
std::move(v));
}
};
class Utils : public UtilsInterface
{
public:
std::string getService(sdbusplus::bus::bus& bus, const char* path,
const char* interface) const override;
std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
const char* path,
const char* interface) const override;
any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName) const override;
void setPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName,
ValueType&& value) const override;
};
inline std::string getService(sdbusplus::bus::bus& bus, const char* path,
const char* interface)
{
return getUtils().getService(bus, path, interface);
}
inline std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
const char* path,
const char* interface)
{
return getUtils().getServices(bus, path, interface);
}
template <typename T>
T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
const char* interface, const char* propertyName)
{
return getUtils().getProperty<T>(bus, service, path, interface,
propertyName);
}
template <typename T>
void setProperty(sdbusplus::bus::bus& bus, const char* service,
const char* path, const char* interface,
const char* propertyName, const T& value)
{
return getUtils().setProperty<T>(bus, service, path, interface,
propertyName, value);
}
} // namespace utils