REST: Add method return support for basic types

Add support for returning the basic D-Bus types,
such as int, string, etc, from methods.

It does this by using the sd_bus_message_read_basic
API to pull the data out of the method response message,
and then converts it to JSON.

Future commits will add array/dict/variant support.

Change-Id: I937d22330a9c2df443942ea84e45d894244388ff
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index 895f436..18b99dd 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -795,9 +795,153 @@
     return r;
 }
 
+template <typename T>
+int readMessageItem(const std::string &typeCode, sdbusplus::message::message &m,
+                    nlohmann::json &data)
+{
+    T value;
+
+    int r = sd_bus_message_read_basic(m.get(), typeCode.front(), &value);
+    if (r < 0)
+    {
+        BMCWEB_LOG_ERROR << "sd_bus_message_read_basic on type " << typeCode
+                         << " failed!";
+        return r;
+    }
+
+    data = value;
+    return 0;
+}
+
 int convertDBusToJSON(const std::string &returnType,
                       sdbusplus::message::message &m, nlohmann::json &response)
 {
+    int r = 0;
+    const std::vector<std::string> returnTypes = dbusArgSplit(returnType);
+
+    nlohmann::json &thisElement = response;
+    for (const std::string &typeCode : returnTypes)
+    {
+        if (returnType.size() > 1)
+        {
+            response.push_back(nlohmann::json{});
+            thisElement = response.back();
+        }
+
+        if (typeCode == "s")
+        {
+            r = readMessageItem<char *>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "g")
+        {
+            r = readMessageItem<char *>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "o")
+        {
+            r = readMessageItem<char *>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "b")
+        {
+            r = readMessageItem<int>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+
+            thisElement = static_cast<bool>(thisElement.get<int>());
+        }
+        else if (typeCode == "u")
+        {
+            r = readMessageItem<uint32_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "i")
+        {
+            r = readMessageItem<int32_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "x")
+        {
+            r = readMessageItem<int64_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "t")
+        {
+            r = readMessageItem<uint64_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "n")
+        {
+            r = readMessageItem<int16_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "q")
+        {
+            r = readMessageItem<uint16_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "y")
+        {
+            r = readMessageItem<uint8_t>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "d")
+        {
+            r = readMessageItem<double>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else if (typeCode == "h")
+        {
+            r = readMessageItem<int>(typeCode, m, thisElement);
+            if (r < 0)
+            {
+                return r;
+            }
+        }
+        else
+        {
+            // TODO: add array, dict, variant support
+            BMCWEB_LOG_ERROR << "Invalid D-Bus signature type " << typeCode;
+            return -2;
+        }
+    }
+
     return 0;
 }