198f42947SShawn McCarney /**
298f42947SShawn McCarney  * Copyright © 2024 IBM Corporation
398f42947SShawn McCarney  *
498f42947SShawn McCarney  * Licensed under the Apache License, Version 2.0 (the "License");
598f42947SShawn McCarney  * you may not use this file except in compliance with the License.
698f42947SShawn McCarney  * You may obtain a copy of the License at
798f42947SShawn McCarney  *
898f42947SShawn McCarney  *     http://www.apache.org/licenses/LICENSE-2.0
998f42947SShawn McCarney  *
1098f42947SShawn McCarney  * Unless required by applicable law or agreed to in writing, software
1198f42947SShawn McCarney  * distributed under the License is distributed on an "AS IS" BASIS,
1298f42947SShawn McCarney  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1398f42947SShawn McCarney  * See the License for the specific language governing permissions and
1498f42947SShawn McCarney  * limitations under the License.
1598f42947SShawn McCarney  */
1698f42947SShawn McCarney #pragma once
1798f42947SShawn McCarney 
1898f42947SShawn McCarney #include "utility.hpp"
1998f42947SShawn McCarney 
2098f42947SShawn McCarney #include <sdbusplus/bus.hpp>
2198f42947SShawn McCarney #include <sdbusplus/bus/match.hpp>
2298f42947SShawn McCarney 
2398f42947SShawn McCarney #include <functional>
2498f42947SShawn McCarney #include <string>
2598f42947SShawn McCarney #include <vector>
2698f42947SShawn McCarney 
2798f42947SShawn McCarney namespace phosphor::power::util
2898f42947SShawn McCarney {
2998f42947SShawn McCarney 
3098f42947SShawn McCarney /**
3198f42947SShawn McCarney  * @class DBusInterfacesFinder
3298f42947SShawn McCarney  *
3398f42947SShawn McCarney  * Class that finds instances of one or more D-Bus interfaces.
3498f42947SShawn McCarney  *
3598f42947SShawn McCarney  * A D-Bus service name and one or more D-Bus interfaces are specified in the
3698f42947SShawn McCarney  * constructor.  The class finds instances of those interfaces that are owned by
3798f42947SShawn McCarney  * the service.
3898f42947SShawn McCarney  *
3998f42947SShawn McCarney  * The class finds the instances using two different methods:
4098f42947SShawn McCarney  * - Registers an InterfacesAdded listener for the specified service.  Class is
4198f42947SShawn McCarney  *   notified when a new interface instance is created on D-Bus.
4298f42947SShawn McCarney  * - Queries the ObjectMapper to find interface instances that already exist.
4398f42947SShawn McCarney  *
4498f42947SShawn McCarney  * Utilizing both methods allows this class to be used before, during, or after
4598f42947SShawn McCarney  * the service has created the interface instances.
4698f42947SShawn McCarney  *
4798f42947SShawn McCarney  * When an interface instance is found, the callback function specified in the
4898f42947SShawn McCarney  * constructor is called.  This function will be called multiple times if
4998f42947SShawn McCarney  * multiple instances are found.
5098f42947SShawn McCarney  */
5198f42947SShawn McCarney class DBusInterfacesFinder
5298f42947SShawn McCarney {
5398f42947SShawn McCarney   public:
5498f42947SShawn McCarney     // Specify which compiler-generated methods we want
5598f42947SShawn McCarney     DBusInterfacesFinder() = delete;
5698f42947SShawn McCarney     DBusInterfacesFinder(const DBusInterfacesFinder&) = delete;
5798f42947SShawn McCarney     DBusInterfacesFinder(DBusInterfacesFinder&&) = delete;
5898f42947SShawn McCarney     DBusInterfacesFinder& operator=(const DBusInterfacesFinder&) = delete;
5998f42947SShawn McCarney     DBusInterfacesFinder& operator=(DBusInterfacesFinder&&) = delete;
6098f42947SShawn McCarney     ~DBusInterfacesFinder() = default;
6198f42947SShawn McCarney 
6298f42947SShawn McCarney     /**
6398f42947SShawn McCarney      * Callback function that is called when an interface instance is found.
6498f42947SShawn McCarney      *
6598f42947SShawn McCarney      * @param path D-Bus object path that implements the interface
6698f42947SShawn McCarney      * @param interface D-Bus interface that was found
6798f42947SShawn McCarney      * @param properties Properties of the D-Bus interface
6898f42947SShawn McCarney      */
6998f42947SShawn McCarney     using Callback = std::function<void(const std::string& path,
7098f42947SShawn McCarney                                         const std::string& interface,
7198f42947SShawn McCarney                                         const DbusPropertyMap& properties)>;
7298f42947SShawn McCarney 
7398f42947SShawn McCarney     /**
7498f42947SShawn McCarney      * Constructor.
7598f42947SShawn McCarney      *
761838dbf9SShawn McCarney      * Note: The callback function may be called immediately by this
771838dbf9SShawn McCarney      * constructor.  For this reason, do not use this constructor in the
781838dbf9SShawn McCarney      * initialization list of constructors in other classes.  Otherwise the
791838dbf9SShawn McCarney      * callback may be called before the other class is fully initialized,
801838dbf9SShawn McCarney      * leading to unpredictable behavior.
811838dbf9SShawn McCarney      *
8298f42947SShawn McCarney      * @param bus D-Bus bus object
8398f42947SShawn McCarney      * @param service D-Bus service that owns the object paths implementing
8498f42947SShawn McCarney      *                the specified interfaces
8598f42947SShawn McCarney      * @param interfaces D-Bus interfaces to find
8698f42947SShawn McCarney      * @param callback Callback function that is called each time an interface
8798f42947SShawn McCarney      *                 instance is found
8898f42947SShawn McCarney      */
89*f5402197SPatrick Williams     explicit DBusInterfacesFinder(
90*f5402197SPatrick Williams         sdbusplus::bus_t& bus, const std::string& service,
91*f5402197SPatrick Williams         const std::vector<std::string>& interfaces, Callback callback);
9298f42947SShawn McCarney 
9398f42947SShawn McCarney     /**
948b098b97SShawn McCarney      * Refind all instances of the interfaces specified in the constructor.
958b098b97SShawn McCarney      *
968b098b97SShawn McCarney      * The callback specified in the constructor will be called for each
978b098b97SShawn McCarney      * instance found.
988b098b97SShawn McCarney      *
998b098b97SShawn McCarney      * This method normally does not need to be called.  New instances are
1008b098b97SShawn McCarney      * automatically detected using an InterfacesAdded listener.  However, this
1018b098b97SShawn McCarney      * method may be useful if the caller is not currently receiving D-Bus
1028b098b97SShawn McCarney      * signals (such as within a loop).
1038b098b97SShawn McCarney      */
refind()1048b098b97SShawn McCarney     void refind()
1058b098b97SShawn McCarney     {
1068b098b97SShawn McCarney         findInterfaces();
1078b098b97SShawn McCarney     }
1088b098b97SShawn McCarney 
1098b098b97SShawn McCarney     /**
11098f42947SShawn McCarney      * Callback function to handle InterfacesAdded D-Bus signals
11198f42947SShawn McCarney      *
11298f42947SShawn McCarney      * @param message Expanded sdbusplus message data
11398f42947SShawn McCarney      */
11498f42947SShawn McCarney     void interfacesAddedCallback(sdbusplus::message_t& message);
11598f42947SShawn McCarney 
11698f42947SShawn McCarney   private:
11798f42947SShawn McCarney     /**
11898f42947SShawn McCarney      * Finds any interface instances that already exist on D-Bus.
11998f42947SShawn McCarney      */
12098f42947SShawn McCarney     void findInterfaces();
12198f42947SShawn McCarney 
12298f42947SShawn McCarney     /**
12398f42947SShawn McCarney      * D-Bus bus object.
12498f42947SShawn McCarney      */
12598f42947SShawn McCarney     sdbusplus::bus_t& bus;
12698f42947SShawn McCarney 
12798f42947SShawn McCarney     /**
12898f42947SShawn McCarney      * D-Bus service that owns the object paths implementing the interfaces.
12998f42947SShawn McCarney      */
13098f42947SShawn McCarney     std::string service;
13198f42947SShawn McCarney 
13298f42947SShawn McCarney     /**
13398f42947SShawn McCarney      * D-Bus interfaces to find.
13498f42947SShawn McCarney      */
13598f42947SShawn McCarney     std::vector<std::string> interfaces;
13698f42947SShawn McCarney 
13798f42947SShawn McCarney     /**
13898f42947SShawn McCarney      * Callback function that is called each time an interface instance is
13998f42947SShawn McCarney      * found.
14098f42947SShawn McCarney      */
14198f42947SShawn McCarney     Callback callback;
14298f42947SShawn McCarney 
14398f42947SShawn McCarney     /**
14498f42947SShawn McCarney      * Match object for InterfacesAdded signals.
14598f42947SShawn McCarney      */
14698f42947SShawn McCarney     sdbusplus::bus::match_t match;
14798f42947SShawn McCarney };
14898f42947SShawn McCarney 
14998f42947SShawn McCarney } // namespace phosphor::power::util
150