Refactor PropertiesChanged handler setup

Most sensor daemons had pretty much the same duplicated open-coded
pattern for setting up PropertiesChanged signal matches; introduce a
helper function to reduce the duplication and make things more readable.

Signed-off-by: Zev Weiss <zev@bewilderbeest.net>
Change-Id: I803a21eea2f6d7fc71b50d54bb8fd57a104f3349
diff --git a/include/Utils.hpp b/include/Utils.hpp
index fdd1d8d..fb543f4 100644
--- a/include/Utils.hpp
+++ b/include/Utils.hpp
@@ -14,6 +14,7 @@
 #include <memory>
 #include <optional>
 #include <regex>
+#include <span>
 #include <string>
 #include <tuple>
 #include <utility>
@@ -337,3 +338,7 @@
                                const double& scaleFactor);
 void setupManufacturingModeMatch(sdbusplus::asio::connection& conn);
 bool getManufacturingMode();
+std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
+    setupPropertiesChangedMatches(
+        sdbusplus::asio::connection& bus, std::span<const char* const> types,
+        const std::function<void(sdbusplus::message_t&)>& handler);
diff --git a/src/ADCSensorMain.cpp b/src/ADCSensorMain.cpp
index 80838bf..471c142 100644
--- a/src/ADCSensorMain.cpp
+++ b/src/ADCSensorMain.cpp
@@ -316,7 +316,6 @@
     systemBus->request_name("xyz.openbmc_project.ADCSensor");
     sdbusplus::asio::object_server objectServer(systemBus);
     boost::container::flat_map<std::string, std::shared_ptr<ADCSensor>> sensors;
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
     auto sensorsChanged =
         std::make_shared<boost::container::flat_set<std::string>>();
 
@@ -401,15 +400,8 @@
         });
     };
 
-    for (const char* type : sensorTypes)
-    {
-        auto match = std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*systemBus),
-            "type='signal',member='PropertiesChanged',path_namespace='" +
-                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
-            eventHandler);
-        matches.emplace_back(std::move(match));
-    }
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
     matches.emplace_back(std::make_unique<sdbusplus::bus::match_t>(
         static_cast<sdbusplus::bus_t&>(*systemBus),
         "type='signal',member='PropertiesChanged',path_namespace='" +
diff --git a/src/ExitAirTempSensor.cpp b/src/ExitAirTempSensor.cpp
index a13b1c5..61a03fb 100644
--- a/src/ExitAirTempSensor.cpp
+++ b/src/ExitAirTempSensor.cpp
@@ -947,7 +947,6 @@
     sdbusplus::asio::object_server objectServer(systemBus);
     std::shared_ptr<ExitAirTempSensor> sensor =
         nullptr; // wait until we find the config
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
 
     io.post([&]() { createSensor(objectServer, sensor, systemBus); });
 
@@ -969,15 +968,8 @@
             }
         });
     };
-    for (const char* type : monitorIfaces)
-    {
-        auto match = std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*systemBus),
-            "type='signal',member='PropertiesChanged',path_namespace='" +
-                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
-            eventHandler);
-        matches.emplace_back(std::move(match));
-    }
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, monitorIfaces, eventHandler);
 
     setupManufacturingModeMatch(*systemBus);
     io.run();
diff --git a/src/ExternalSensorMain.cpp b/src/ExternalSensorMain.cpp
index afde3e8..f912750 100644
--- a/src/ExternalSensorMain.cpp
+++ b/src/ExternalSensorMain.cpp
@@ -345,7 +345,6 @@
     sdbusplus::asio::object_server objectServer(systemBus);
     boost::container::flat_map<std::string, std::shared_ptr<ExternalSensor>>
         sensors;
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
     auto sensorsChanged =
         std::make_shared<boost::container::flat_set<std::string>>();
     boost::asio::steady_timer reaperTimer(io);
@@ -392,12 +391,9 @@
         });
     };
 
-    auto match = std::make_unique<sdbusplus::bus::match_t>(
-        static_cast<sdbusplus::bus_t&>(*systemBus),
-        "type='signal',member='PropertiesChanged',path_namespace='" +
-            std::string(inventoryPath) + "',arg0namespace='" + sensorType + "'",
-        eventHandler);
-    matches.emplace_back(std::move(match));
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(
+            *systemBus, std::to_array<const char*>({sensorType}), eventHandler);
 
     if constexpr (debug)
     {
diff --git a/src/FanMain.cpp b/src/FanMain.cpp
index 13902c7..87e27c6 100644
--- a/src/FanMain.cpp
+++ b/src/FanMain.cpp
@@ -525,7 +525,6 @@
         tachSensors;
     boost::container::flat_map<std::string, std::unique_ptr<PwmSensor>>
         pwmSensors;
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
     auto sensorsChanged =
         std::make_shared<boost::container::flat_set<std::string>>();
 
@@ -562,15 +561,8 @@
         });
     };
 
-    for (const char* type : sensorTypes)
-    {
-        auto match = std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*systemBus),
-            "type='signal',member='PropertiesChanged',path_namespace='" +
-                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
-            eventHandler);
-        matches.emplace_back(std::move(match));
-    }
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
 
     // redundancy sensor
     std::function<void(sdbusplus::message_t&)> redundancyHandler =
diff --git a/src/HwmonTempMain.cpp b/src/HwmonTempMain.cpp
index 7649cb7..5c9ea10 100644
--- a/src/HwmonTempMain.cpp
+++ b/src/HwmonTempMain.cpp
@@ -524,7 +524,6 @@
     sdbusplus::asio::object_server objectServer(systemBus);
     boost::container::flat_map<std::string, std::shared_ptr<HwmonTempSensor>>
         sensors;
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
     auto sensorsChanged =
         std::make_shared<boost::container::flat_set<std::string>>();
 
@@ -559,16 +558,8 @@
         });
     };
 
-    for (const char* type : sensorTypes)
-    {
-        auto match = std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*systemBus),
-            "type='signal',member='PropertiesChanged',path_namespace='" +
-                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
-            eventHandler);
-        matches.emplace_back(std::move(match));
-    }
-
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
     setupManufacturingModeMatch(*systemBus);
 
     // Watch for entity-manager to remove configuration interfaces
diff --git a/src/IntelCPUSensorMain.cpp b/src/IntelCPUSensorMain.cpp
index 7ca6bc1..ea144de 100644
--- a/src/IntelCPUSensorMain.cpp
+++ b/src/IntelCPUSensorMain.cpp
@@ -716,7 +716,6 @@
     boost::container::flat_set<CPUConfig> cpuConfigs;
 
     sdbusplus::asio::object_server objectServer(systemBus);
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
     boost::asio::deadline_timer pingTimer(io);
     boost::asio::deadline_timer creationTimer(io);
     boost::asio::deadline_timer filterTimer(io);
@@ -766,16 +765,8 @@
         });
     };
 
-    for (const char* type : sensorTypes)
-    {
-        auto match = std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*systemBus),
-            "type='signal',member='PropertiesChanged',path_namespace='" +
-                std::string(inventoryPath) + "',arg0namespace='" +
-                configPrefix + type + "'",
-            eventHandler);
-        matches.emplace_back(std::move(match));
-    }
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
 
     systemBus->request_name("xyz.openbmc_project.IntelCPUSensor");
 
diff --git a/src/IntrusionSensorMain.cpp b/src/IntrusionSensorMain.cpp
index 2745c08..fcf55d2 100644
--- a/src/IntrusionSensorMain.cpp
+++ b/src/IntrusionSensorMain.cpp
@@ -458,11 +458,9 @@
         }
     };
 
-    auto eventMatch = std::make_unique<sdbusplus::bus::match_t>(
-        static_cast<sdbusplus::bus_t&>(*systemBus),
-        "type='signal',member='PropertiesChanged',path_namespace='" +
-            std::string(inventoryPath) + "',arg0namespace='" + sensorType + "'",
-        eventHandler);
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(
+            *systemBus, std::to_array<const char*>({sensorType}), eventHandler);
 
     if (initializeLanStatus(systemBus))
     {
diff --git a/src/IpmbSensor.cpp b/src/IpmbSensor.cpp
index 88f6bb3..280ef24 100644
--- a/src/IpmbSensor.cpp
+++ b/src/IpmbSensor.cpp
@@ -642,12 +642,10 @@
         });
     };
 
-    sdbusplus::bus::match_t configMatch(
-        static_cast<sdbusplus::bus_t&>(*systemBus),
-        "type='signal',member='PropertiesChanged',path_namespace='" +
-            std::string(inventoryPath) + "',arg0namespace='" + configInterface +
-            "'",
-        eventHandler);
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(
+            *systemBus, std::to_array<const char*>({configInterface}),
+            eventHandler);
 
     sdbusplus::bus::match_t powerChangeMatch(
         static_cast<sdbusplus::bus_t&>(*systemBus),
diff --git a/src/MCUTempSensor.cpp b/src/MCUTempSensor.cpp
index b856bdb..39b7259 100644
--- a/src/MCUTempSensor.cpp
+++ b/src/MCUTempSensor.cpp
@@ -296,16 +296,10 @@
         });
     };
 
-    sdbusplus::bus::match_t configMatch(
-        static_cast<sdbusplus::bus_t&>(*systemBus),
-        "type='signal',member='PropertiesChanged',"
-        "path_namespace='" +
-            std::string(inventoryPath) +
-            "',"
-            "arg0namespace='" +
-            configInterface + "'",
-        eventHandler);
-
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(
+            *systemBus, std::to_array<const char*>({configInterface}),
+            eventHandler);
     setupManufacturingModeMatch(*systemBus);
     io.run();
     return 0;
diff --git a/src/NVMeSensorMain.cpp b/src/NVMeSensorMain.cpp
index dc85f70..ae86e6b 100644
--- a/src/NVMeSensorMain.cpp
+++ b/src/NVMeSensorMain.cpp
@@ -254,12 +254,10 @@
         });
     };
 
-    sdbusplus::bus::match_t configMatch(
-        static_cast<sdbusplus::bus_t&>(*systemBus),
-        "type='signal',member='PropertiesChanged',path_namespace='" +
-            std::string(inventoryPath) + "',arg0namespace='" +
-            std::string(NVMeSensor::configType) + "'",
-        eventHandler);
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(
+            *systemBus, std::to_array<const char*>({NVMeSensor::configType}),
+            eventHandler);
 
     // Watch for entity-manager to remove configuration interfaces
     // so the corresponding sensors can be removed.
diff --git a/src/PSUSensorMain.cpp b/src/PSUSensorMain.cpp
index 0084b55..a69ae48 100644
--- a/src/PSUSensorMain.cpp
+++ b/src/PSUSensorMain.cpp
@@ -1068,7 +1068,6 @@
 
     systemBus->request_name("xyz.openbmc_project.PSUSensor");
     sdbusplus::asio::object_server objectServer(systemBus);
-    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
     auto sensorsChanged =
         std::make_shared<boost::container::flat_set<std::string>>();
 
@@ -1098,16 +1097,8 @@
             });
         };
 
-    for (const char* type : sensorTypes)
-    {
-        auto match = std::make_unique<sdbusplus::bus::match_t>(
-            static_cast<sdbusplus::bus_t&>(*systemBus),
-            "type='signal',member='PropertiesChanged',path_namespace='" +
-                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
-            eventHandler);
-        matches.emplace_back(std::move(match));
-    }
-
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches =
+        setupPropertiesChangedMatches(*systemBus, sensorTypes, eventHandler);
     setupManufacturingModeMatch(*systemBus);
     io.run();
 }
diff --git a/src/Utils.cpp b/src/Utils.cpp
index 60c05d6..66464e8 100644
--- a/src/Utils.cpp
+++ b/src/Utils.cpp
@@ -707,3 +707,21 @@
 {
     return manufacturingMode;
 }
+
+std::vector<std::unique_ptr<sdbusplus::bus::match_t>>
+    setupPropertiesChangedMatches(
+        sdbusplus::asio::connection& bus, std::span<const char* const> types,
+        const std::function<void(sdbusplus::message_t&)>& handler)
+{
+    std::vector<std::unique_ptr<sdbusplus::bus::match_t>> matches;
+    for (const char* type : types)
+    {
+        auto match = std::make_unique<sdbusplus::bus::match_t>(
+            static_cast<sdbusplus::bus_t&>(bus),
+            "type='signal',member='PropertiesChanged',path_namespace='" +
+                std::string(inventoryPath) + "',arg0namespace='" + type + "'",
+            handler);
+        matches.emplace_back(std::move(match));
+    }
+    return matches;
+}