blob: 43e1f0d6ee949079247d49046bda5fe965509683 [file] [log] [blame]
Lei YUfb19d992020-09-25 17:10:49 +08001#pragma once
2
3#include <sdbusplus/bus.hpp>
4
5#include <experimental/any>
6#include <string>
7#include <vector>
8
9namespace utils
10{
11
12class UtilsInterface;
13
14// Due to a libstdc++ bug, we got compile error using std::any with gmock.
15// A temporary workaround is to use std::experimental::any.
16// See details in https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90415
17using std::experimental::any;
18using std::experimental::any_cast;
19
Lei YU2e097462020-09-27 14:31:04 +080020using ValueType =
21 std::variant<bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t,
22 uint64_t, double, std::string>;
Lei YUfb19d992020-09-25 17:10:49 +080023/**
24 * @brief Get the implementation of UtilsInterface
25 */
26const UtilsInterface& getUtils();
27
28/** @brief Get service name from object path and interface
29 *
30 * @param[in] bus - The Dbus bus object
31 * @param[in] path - The Dbus object path
32 * @param[in] interface - The Dbus interface
33 *
34 * @return The name of the service
35 */
36std::string getService(sdbusplus::bus::bus& bus, const char* path,
37 const char* interface);
38
39/** @brief Get all the service names from object path and interface
40 *
41 * @param[in] bus - The Dbus bus object
42 * @param[in] path - The Dbus object path
43 * @param[in] interface - The Dbus interface
44 *
45 * @return The name of the services
46 */
47std::vector<std::string> getServices(sdbusplus::bus::bus& bus, const char* path,
48 const char* interface);
49
50/** @brief The template function to get property from the requested dbus path
51 *
52 * @param[in] bus - The Dbus bus object
53 * @param[in] service - The Dbus service name
54 * @param[in] path - The Dbus object path
55 * @param[in] interface - The Dbus interface
56 * @param[in] propertyName - The property name to get
57 *
58 * @return The value of the property
59 */
60template <typename T>
61T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
62 const char* interface, const char* propertyName);
63
Lei YU2e097462020-09-27 14:31:04 +080064template <typename T>
65void setProperty(sdbusplus::bus::bus& bus, const char* service,
66 const char* path, const char* interface,
67 const char* propertyName, const T& value);
68
Lei YUfb19d992020-09-25 17:10:49 +080069/**
70 * @brief The interface for utils
71 */
72class UtilsInterface
73{
74 public:
75 // For now the code needs to get property for Present and Version
76 using PropertyType = std::variant<std::string, bool>;
77
78 virtual ~UtilsInterface() = default;
79
80 virtual std::string getService(sdbusplus::bus::bus& bus, const char* path,
81 const char* interface) const = 0;
82
83 virtual std::vector<std::string>
84 getServices(sdbusplus::bus::bus& bus, const char* path,
85 const char* interface) const = 0;
86
87 virtual any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
88 const char* path, const char* interface,
89 const char* propertyName) const = 0;
90
Lei YU2e097462020-09-27 14:31:04 +080091 virtual void setPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
92 const char* path, const char* interface,
93 const char* propertyName,
94 ValueType&& value) const = 0;
95
Lei YUfb19d992020-09-25 17:10:49 +080096 template <typename T>
97 T getProperty(sdbusplus::bus::bus& bus, const char* service,
98 const char* path, const char* interface,
99 const char* propertyName) const
100 {
George Liu2ae54232024-04-03 09:40:27 +0800101 any result = getPropertyImpl(bus, service, path, interface,
102 propertyName);
Lei YUfb19d992020-09-25 17:10:49 +0800103 auto value = any_cast<PropertyType>(result);
104 return std::get<T>(value);
105 }
Lei YU2e097462020-09-27 14:31:04 +0800106
107 template <typename T>
108 void setProperty(sdbusplus::bus::bus& bus, const char* service,
109 const char* path, const char* interface,
110 const char* propertyName, const T& value) const
111 {
112 ValueType v(value);
113 setPropertyImpl(bus, service, path, interface, propertyName,
114 std::move(v));
115 }
Lei YUfb19d992020-09-25 17:10:49 +0800116};
117
118class Utils : public UtilsInterface
119{
120 public:
121 std::string getService(sdbusplus::bus::bus& bus, const char* path,
122 const char* interface) const override;
123
124 std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
125 const char* path,
126 const char* interface) const override;
127
128 any getPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
129 const char* path, const char* interface,
130 const char* propertyName) const override;
Lei YU2e097462020-09-27 14:31:04 +0800131
132 void setPropertyImpl(sdbusplus::bus::bus& bus, const char* service,
133 const char* path, const char* interface,
134 const char* propertyName,
135 ValueType&& value) const override;
Lei YUfb19d992020-09-25 17:10:49 +0800136};
137
138inline std::string getService(sdbusplus::bus::bus& bus, const char* path,
139 const char* interface)
140{
141 return getUtils().getService(bus, path, interface);
142}
143
144inline std::vector<std::string> getServices(sdbusplus::bus::bus& bus,
145 const char* path,
146 const char* interface)
147{
148 return getUtils().getServices(bus, path, interface);
149}
150
151template <typename T>
152T getProperty(sdbusplus::bus::bus& bus, const char* service, const char* path,
153 const char* interface, const char* propertyName)
154{
155 return getUtils().getProperty<T>(bus, service, path, interface,
156 propertyName);
157}
158
Lei YU2e097462020-09-27 14:31:04 +0800159template <typename T>
160void setProperty(sdbusplus::bus::bus& bus, const char* service,
161 const char* path, const char* interface,
162 const char* propertyName, const T& value)
163{
164 return getUtils().setProperty<T>(bus, service, path, interface,
165 propertyName, value);
166}
167
Lei YUfb19d992020-09-25 17:10:49 +0800168} // namespace utils