usb: Add utility for D-Bus

Putting all D-Bus related operation to the utils file.

Tested: Call the set/getProperty functions locally and successfully
set/get the corresponding attribute value.

Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: I0e0c33fd6ec5db3a47babaf417b0c708709e580b
diff --git a/usb/meson.build b/usb/meson.build
index 0de8e33..9ac5876 100644
--- a/usb/meson.build
+++ b/usb/meson.build
@@ -10,6 +10,7 @@
 source = [
     'usb_manager_main.cpp',
     'usb_manager.cpp',
+    '../utils.cpp',
     ]
 
 phosphor_logging_dep = dependency(
@@ -24,6 +25,7 @@
     dependencies: [
         CLI11_dep,
         phosphor_logging_dep,
+        sdbusplus_dep,
     ],
     install: true,
     install_dir: get_option('bindir')
diff --git a/utils.cpp b/utils.cpp
index 38de0e4..410ddc8 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -41,6 +41,45 @@
     return response[0].first;
 }
 
+const PropertyValue getProperty(sdbusplus::bus::bus& bus,
+                                const std::string& objectPath,
+                                const std::string& interface,
+                                const std::string& propertyName)
+{
+    PropertyValue value{};
+    auto service = getService(bus, objectPath, interface);
+    if (service.empty())
+    {
+        return value;
+    }
+
+    auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
+                                      "org.freedesktop.DBus.Properties", "Get");
+    method.append(interface, propertyName);
+
+    auto reply = bus.call(method);
+    reply.read(value);
+
+    return value;
+}
+
+void setProperty(sdbusplus::bus::bus& bus, const std::string& objectPath,
+                 const std::string& interface, const std::string& propertyName,
+                 const PropertyValue& value)
+{
+    auto service = getService(bus, objectPath, interface);
+    if (service.empty())
+    {
+        return;
+    }
+
+    auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
+                                      "org.freedesktop.DBus.Properties", "Set");
+    method.append(interface.c_str(), propertyName.c_str(), value);
+
+    bus.call_noreply(method);
+}
+
 void mergeFiles(std::vector<std::string>& srcFiles, std::string& dstFile)
 {
     std::ofstream outFile(dstFile, std::ios::out);
diff --git a/utils.hpp b/utils.hpp
index a6db7f9..fc8144c 100644
--- a/utils.hpp
+++ b/utils.hpp
@@ -9,6 +9,8 @@
 namespace utils
 {
 
+using PropertyValue = std::variant<std::string>;
+
 /**
  * @brief Get the bus service
  *
@@ -17,6 +19,36 @@
 std::string getService(sdbusplus::bus::bus& bus, const std::string& path,
                        const std::string& interface);
 
+/** @brief Get property(type: variant)
+ *
+ *  @param[in] bus              -   bus handler
+ *  @param[in] objectPath       -   D-Bus object path
+ *  @param[in] interface        -   D-Bus interface
+ *  @param[in] propertyName     -   D-Bus property name
+ *
+ *  @return The value of the property(type: variant)
+ *
+ *  @throw sdbusplus::exception::exception when it fails
+ */
+const PropertyValue getProperty(sdbusplus::bus::bus& bus,
+                                const std::string& objectPath,
+                                const std::string& interface,
+                                const std::string& propertyName);
+
+/** @brief Set D-Bus property
+ *
+ *  @param[in] bus              -   bus handler
+ *  @param[in] objectPath       -   D-Bus object path
+ *  @param[in] interface        -   D-Bus interface
+ *  @param[in] propertyName     -   D-Bus property name
+ *  @param[in] value            -   The value to be set
+ *
+ *  @throw sdbusplus::exception::exception when it fails
+ */
+void setProperty(sdbusplus::bus::bus& bus, const std::string& objectPath,
+                 const std::string& interface, const std::string& propertyName,
+                 const PropertyValue& value);
+
 /**
  * @brief Merge more files
  *