sensor-cache: Initial commit

This is the initial commit of a series of changes for caching the
sensors in ipmid, so that the ipmi sensor/sdr related handlers could use
the cached values instead of getting the sensors from DBus.

The goal is to improve the ipmi sensor list's performance.
With all the patches in the series, the ipmitool sensor list time on
g220a (140+ sensors) is reduced from 20s+ to about 11s.

Tested: Manually verify the matches are working correctly in QEMU.

Signed-off-by: Lei YU <yulei.sh@bytedance.com>
Change-Id: I4c4be8613dd89b5a83d8ff59354a8a3991e98cbf
diff --git a/sensorhandler.cpp b/sensorhandler.cpp
index 143982d..e842355 100644
--- a/sensorhandler.cpp
+++ b/sensorhandler.cpp
@@ -86,6 +86,37 @@
     std::unordered_map<uint8_t, get_sdr::GetSensorThresholdsResponse>;
 SensorThresholdMap sensorThresholdMap __attribute__((init_priority(101)));
 
+std::map<uint8_t, std::unique_ptr<sdbusplus::bus::match::match>>
+    sensorAddedMatches __attribute__((init_priority(101)));
+std::map<uint8_t, std::unique_ptr<sdbusplus::bus::match::match>>
+    sensorUpdatedMatches __attribute__((init_priority(101)));
+
+void initSensorMatches()
+{
+    using namespace sdbusplus::bus::match::rules;
+    sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+    for (const auto& s : ipmi::sensor::sensors)
+    {
+        sensorAddedMatches.emplace(
+            s.first,
+            std::make_unique<sdbusplus::bus::match::match>(
+                bus, interfacesAdded() + argNpath(0, s.second.sensorPath),
+                [id = s.first, obj = s.second.sensorPath](auto& /*msg*/) {
+                    // TODO
+                }));
+        sensorUpdatedMatches.emplace(
+            s.first,
+            std::make_unique<sdbusplus::bus::match::match>(
+                bus,
+                type::signal() + path(s.second.sensorPath) +
+                    member("PropertiesChanged"s) +
+                    interface("org.freedesktop.DBus.Properties"s),
+                [id = s.first, obj = s.second.sensorPath](auto& /*msg*/) {
+                    // TODO
+                }));
+    }
+}
+
 int get_bus_for_path(const char* path, char** busname)
 {
     return mapper_get_service(bus, path, busname);
@@ -1289,6 +1320,10 @@
     // Do not register the hander if it dynamic sensors stack is used.
 
 #ifndef FEATURE_DYNAMIC_SENSORS
+
+    // Initialize the sensor matches
+    initSensorMatches();
+
     // <Set Sensor Reading and Event Status>
     ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnSensor,
                           ipmi::sensor_event::cmdSetSensorReadingAndEvtSts,