Create class for finding D-Bus interfaces
Create a class for finding instances of D-Bus interfaces. The class
finds existing instances using the ObjectMapper. It also finds new
instances using an InterfacesAdded listener.
Tested:
* See test plan at
https://gist.github.com/smccarney/67d7719f0cf9cea2d134b0796aa408da
Change-Id: Ia6fba9cb69ad73607dc971dd6d63ba2efecabe0d
Signed-off-by: Shawn McCarney <shawnmm@us.ibm.com>
diff --git a/dbus_interfaces_finder.hpp b/dbus_interfaces_finder.hpp
new file mode 100644
index 0000000..35a80c7
--- /dev/null
+++ b/dbus_interfaces_finder.hpp
@@ -0,0 +1,128 @@
+/**
+ * Copyright © 2024 IBM Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#pragma once
+
+#include "utility.hpp"
+
+#include <sdbusplus/bus.hpp>
+#include <sdbusplus/bus/match.hpp>
+
+#include <functional>
+#include <string>
+#include <vector>
+
+namespace phosphor::power::util
+{
+
+/**
+ * @class DBusInterfacesFinder
+ *
+ * Class that finds instances of one or more D-Bus interfaces.
+ *
+ * A D-Bus service name and one or more D-Bus interfaces are specified in the
+ * constructor. The class finds instances of those interfaces that are owned by
+ * the service.
+ *
+ * The class finds the instances using two different methods:
+ * - Registers an InterfacesAdded listener for the specified service. Class is
+ * notified when a new interface instance is created on D-Bus.
+ * - Queries the ObjectMapper to find interface instances that already exist.
+ *
+ * Utilizing both methods allows this class to be used before, during, or after
+ * the service has created the interface instances.
+ *
+ * When an interface instance is found, the callback function specified in the
+ * constructor is called. This function will be called multiple times if
+ * multiple instances are found.
+ */
+class DBusInterfacesFinder
+{
+ public:
+ // Specify which compiler-generated methods we want
+ DBusInterfacesFinder() = delete;
+ DBusInterfacesFinder(const DBusInterfacesFinder&) = delete;
+ DBusInterfacesFinder(DBusInterfacesFinder&&) = delete;
+ DBusInterfacesFinder& operator=(const DBusInterfacesFinder&) = delete;
+ DBusInterfacesFinder& operator=(DBusInterfacesFinder&&) = delete;
+ ~DBusInterfacesFinder() = default;
+
+ /**
+ * Callback function that is called when an interface instance is found.
+ *
+ * @param path D-Bus object path that implements the interface
+ * @param interface D-Bus interface that was found
+ * @param properties Properties of the D-Bus interface
+ */
+ using Callback = std::function<void(const std::string& path,
+ const std::string& interface,
+ const DbusPropertyMap& properties)>;
+
+ /**
+ * Constructor.
+ *
+ * @param bus D-Bus bus object
+ * @param service D-Bus service that owns the object paths implementing
+ * the specified interfaces
+ * @param interfaces D-Bus interfaces to find
+ * @param callback Callback function that is called each time an interface
+ * instance is found
+ */
+ explicit DBusInterfacesFinder(sdbusplus::bus_t& bus,
+ const std::string& service,
+ const std::vector<std::string>& interfaces,
+ Callback callback);
+
+ /**
+ * Callback function to handle InterfacesAdded D-Bus signals
+ *
+ * @param message Expanded sdbusplus message data
+ */
+ void interfacesAddedCallback(sdbusplus::message_t& message);
+
+ private:
+ /**
+ * Finds any interface instances that already exist on D-Bus.
+ */
+ void findInterfaces();
+
+ /**
+ * D-Bus bus object.
+ */
+ sdbusplus::bus_t& bus;
+
+ /**
+ * D-Bus service that owns the object paths implementing the interfaces.
+ */
+ std::string service;
+
+ /**
+ * D-Bus interfaces to find.
+ */
+ std::vector<std::string> interfaces;
+
+ /**
+ * Callback function that is called each time an interface instance is
+ * found.
+ */
+ Callback callback;
+
+ /**
+ * Match object for InterfacesAdded signals.
+ */
+ sdbusplus::bus::match_t match;
+};
+
+} // namespace phosphor::power::util