REST: Add method return support for structs
A struct is in its own sd_bus_message container,
and the output JSON looks like an array.
Change-Id: Ie8e5848a5fa9bc9605f5dda06dc1b5d7be4dea3c
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/include/openbmc_dbus_rest.hpp b/include/openbmc_dbus_rest.hpp
index a9a6a10..a5024be 100644
--- a/include/openbmc_dbus_rest.hpp
+++ b/include/openbmc_dbus_rest.hpp
@@ -954,6 +954,47 @@
return 0;
}
+int readStructFromMessage(const std::string &typeCode,
+ sdbusplus::message::message &m, nlohmann::json &data)
+{
+ if (typeCode.size() < 3)
+ {
+ BMCWEB_LOG_ERROR << "Type code " << typeCode
+ << " too small for a struct";
+ return -1;
+ }
+
+ std::string containedTypes = typeCode.substr(1, typeCode.size() - 2);
+ std::vector<std::string> types = dbusArgSplit(containedTypes);
+
+ int r = sd_bus_message_enter_container(m.get(), SD_BUS_TYPE_STRUCT,
+ containedTypes.c_str());
+ if (r < 0)
+ {
+ BMCWEB_LOG_ERROR << "sd_bus_message_enter_container failed with rc "
+ << r;
+ return r;
+ }
+
+ for (const std::string &type : types)
+ {
+ data.push_back(nlohmann::json());
+ r = convertDBusToJSON(type, m, data.back());
+ if (r < 0)
+ {
+ return r;
+ }
+ }
+
+ r = sd_bus_message_exit_container(m.get());
+ if (r < 0)
+ {
+ BMCWEB_LOG_ERROR << "sd_bus_message_exit_container failed";
+ return r;
+ }
+ return 0;
+}
+
int convertDBusToJSON(const std::string &returnType,
sdbusplus::message::message &m, nlohmann::json &response)
{
@@ -1083,9 +1124,18 @@
return r;
}
}
+ else if (boost::starts_with(typeCode, "(") &&
+ boost::ends_with(typeCode, ")"))
+ {
+ r = readStructFromMessage(typeCode, m, thisElement);
+ if (r < 0)
+ {
+ return r;
+ }
+ }
else
{
- // TODO: add struct, variant support
+ // TODO: add variant support
BMCWEB_LOG_ERROR << "Invalid D-Bus signature type " << typeCode;
return -2;
}