sdbus++: add server method for set-property

Add a method to the server bindings that sets properties
by looking up the name from a string.

Change-Id: I7e9081b66dfeffd394155a574c2178a7cd039e2a
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Signed-off-by: Brad Bishop <bradleyb@fuzziesquirrel.com>
diff --git a/sdbusplus/message/types.hpp b/sdbusplus/message/types.hpp
index 4daebf3..a65bc31 100644
--- a/sdbusplus/message/types.hpp
+++ b/sdbusplus/message/types.hpp
@@ -16,8 +16,11 @@
 namespace message
 {
 
+namespace variant_ns = mapbox::util;
+
 template <typename ...Args>
-using variant = mapbox::util::variant<Args...>;
+using variant = variant_ns::variant<Args...>;
+
 
 namespace types
 {
diff --git a/tools/sdbusplus/templates/interface.mako.server.cpp b/tools/sdbusplus/templates/interface.mako.server.cpp
index aec8cfb..dceeac4 100644
--- a/tools/sdbusplus/templates/interface.mako.server.cpp
+++ b/tools/sdbusplus/templates/interface.mako.server.cpp
@@ -133,6 +133,22 @@
 }
     % endfor
 
+    % if interface.properties:
+void ${classname}::setPropertyByName(const std::string& name,
+                                     const PropertiesVariant& val)
+{
+        % for p in interface.properties:
+    if (name == "${p.name}")
+    {
+        auto& v = message::variant_ns::get<${p.cppTypeParam(interface.name)}>(\
+val);
+        ${p.camelCase}(v);
+        return;
+    }
+        % endfor
+}
+
+    % endif
     % for e in interface.enums:
 
 namespace
diff --git a/tools/sdbusplus/templates/interface.mako.server.hpp b/tools/sdbusplus/templates/interface.mako.server.hpp
index 1879fd8..440fcce 100644
--- a/tools/sdbusplus/templates/interface.mako.server.hpp
+++ b/tools/sdbusplus/templates/interface.mako.server.hpp
@@ -5,6 +5,10 @@
 <%
     namespaces = interface.name.split('.')
     classname = namespaces.pop()
+
+    def setOfPropertyTypes():
+        return set(p.cppTypeParam(interface.name) for p in
+                   interface.properties);
 %>
 namespace sdbusplus
 {
@@ -49,6 +53,11 @@
         };
     % endfor
 
+    % if interface.properties:
+        using PropertiesVariant = sdbusplus::message::variant<
+                ${",\n                ".join(setOfPropertyTypes())}>;
+
+    % endif
     % for m in interface.methods:
 ${ m.cpp_prototype(loader, interface=interface, ptype='header') }
     % endfor
@@ -65,6 +74,15 @@
 ${p.camelCase}(${p.cppTypeParam(interface.name)} value);
     % endfor
 
+    % if interface.properties:
+        /** @brief Sets a property by name.
+         *  @param[in] name - A string representation of the property name.
+         *  @param[in] val - A variant containing the value to set.
+         */
+        void setPropertyByName(const std::string& name,
+                               const PropertiesVariant& val);
+
+    % endif
     % for e in interface.enums:
     /** @brief Convert a string to an appropriate enum value.
      *  @param[in] s - The string to convert in the form of