Add getSubtree and getAllProperties functions
These will be used to get callout information from
the inventory.
Also added a helper function getService to find a service
name in the GetSubtree data based on an object
path and interface name.
Tested: The functions work when called in future commit.
Change-Id: Ib9af94263506041c353fa813167051559c30bcac
Signed-off-by: Matt Spinler <spinler@us.ibm.com>
diff --git a/dbus.cpp b/dbus.cpp
index 17ad210..06b0078 100644
--- a/dbus.cpp
+++ b/dbus.cpp
@@ -21,6 +21,13 @@
namespace logging
{
+constexpr auto MAPPER_BUSNAME = "xyz.openbmc_project.ObjectMapper";
+constexpr auto MAPPER_PATH = "/xyz/openbmc_project/object_mapper";
+constexpr auto MAPPER_IFACE = "xyz.openbmc_project.ObjectMapper";
+constexpr auto PROPERTY_IFACE = "org.freedesktop.DBus.Properties";
+
+using namespace phosphor::logging;
+
ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
const std::string& service,
const std::string& objPath)
@@ -35,8 +42,8 @@
if (reply.is_method_error())
{
- using namespace phosphor::logging;
log<level::ERR>("Failed to get managed objects",
+ entry("SERVICE=%s", service.c_str()),
entry("PATH=%s", objPath.c_str()));
}
else
@@ -46,5 +53,81 @@
return interfaces;
}
+
+DbusPropertyMap getAllProperties(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& interface)
+{
+ DbusPropertyMap properties;
+
+ auto method = bus.new_method_call(service.c_str(), objPath.c_str(),
+ PROPERTY_IFACE, "GetAll");
+ method.append(interface);
+ auto reply = bus.call(method);
+
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Failed to get all properties",
+ entry("SERVICE=%s", service.c_str()),
+ entry("PATH=%s", objPath.c_str()),
+ entry("INTERFACE=%s", interface.c_str()));
+ }
+ else
+ {
+ reply.read(properties);
+ }
+
+ return properties;
+}
+
+DbusSubtree getSubtree(sdbusplus::bus::bus& bus, const std::string& root,
+ size_t depth, const std::string& interface)
+{
+ DbusSubtree tree;
+
+ auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH, MAPPER_IFACE,
+ "GetSubTree");
+ method.append(root);
+ method.append(depth);
+ method.append(std::vector<std::string>({interface}));
+ auto reply = bus.call(method);
+
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Failed to get subtree", entry("ROOT=%s", root.c_str()),
+ entry("INTERFACE=%s", interface.c_str()));
+ }
+ else
+ {
+ reply.read(tree);
+ }
+
+ return tree;
+}
+
+DbusService getService(const std::string& objPath, const std::string& interface,
+ const DbusSubtree& tree)
+{
+ DbusService service;
+
+ auto services = tree.find(objPath);
+ if (services != tree.end())
+ {
+ auto s = std::find_if(services->second.begin(), services->second.end(),
+ [&interface](const auto& entry) {
+ auto i =
+ std::find(entry.second.begin(),
+ entry.second.end(), interface);
+ return i != entry.second.end();
+ });
+ if (s != services->second.end())
+ {
+ service = s->first;
+ }
+ }
+
+ return service;
+}
}
}
diff --git a/dbus.hpp b/dbus.hpp
index d3c6152..392dd8a 100644
--- a/dbus.hpp
+++ b/dbus.hpp
@@ -12,6 +12,8 @@
using DbusInterface = std::string;
using DbusProperty = std::string;
+using DbusService = std::string;
+using DbusPath = std::string;
using Value = sdbusplus::message::variant<bool, uint32_t, uint64_t, std::string,
std::vector<std::string>>;
@@ -22,6 +24,9 @@
using ObjectValueTree =
std::map<sdbusplus::message::object_path, DbusInterfaceMap>;
+using DbusSubtree =
+ std::map<DbusPath, std::map<DbusService, DbusInterfaceList>>;
+
/**
* Returns the managed objects for an object path and service
*
@@ -37,5 +42,53 @@
ObjectValueTree getManagedObjects(sdbusplus::bus::bus& bus,
const std::string& service,
const std::string& objPath);
+
+/**
+ * Returns the subtree for a root, depth, and interface.
+ *
+ * Returns an empty map if there are any failures.
+ *
+ * @param[in] bus - the D-Bus object
+ * @param[in] root - the point from which to provide results
+ * @param[in] depth - the number of path elements to descend
+ *
+ * @return DbusSubtree - A map of object paths to their
+ * services and interfaces.
+ */
+DbusSubtree getSubtree(sdbusplus::bus::bus& bus, const std::string& root,
+ size_t depth, const std::string& interface);
+
+/**
+ * Get the D-Bus service name for the object path and interface from
+ * the data returned from a GetSubTree call.
+ *
+ * Returns an empty string if the service can't be found.
+ *
+ * @param[in] objPath - the D-Bus object path
+ * @param[in] interface - the D-Bus interface name
+ * @param[in] tree - the D-Bus GetSubTree response
+ *
+ * @return string - the service name
+ */
+DbusService getService(const std::string& objPath, const std::string& interface,
+ const DbusSubtree& tree);
+
+/**
+ * Returns all properties on a particular interface on a
+ * particular D-Bus object.
+ *
+ * Returns an empty map if there are any failures.
+ *
+ * @param[in] bus - the D-Bus object
+ * @param[in] service - the D-Bus service name
+ * @param[in] objPath - the D-Bus object path
+ * @param[in] interface - the D-Bus interface name
+ *
+ * @return DbusPropertyMap - The map of property names to values
+ */
+DbusPropertyMap getAllProperties(sdbusplus::bus::bus& bus,
+ const std::string& service,
+ const std::string& objPath,
+ const std::string& interface);
}
}