FruDevice: Add found I2CDevices

With this Entity Manager can probe on there being
something available at a particular bus/address, even
if it has no fru.

Tested: Compared with dbus with i2cdetect and saw
devices

Change-Id: I9aaf2d1bd2878805c741eb49ac0a3996aad5ce36
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/FruDevice.cpp b/src/FruDevice.cpp
index 005ca67..8c33a3a 100644
--- a/src/FruDevice.cpp
+++ b/src/FruDevice.cpp
@@ -69,6 +69,10 @@
 
 static BusMap busMap;
 
+static boost::container::flat_map<
+    std::pair<size_t, size_t>, std::shared_ptr<sdbusplus::asio::dbus_interface>>
+    foundDevices;
+
 boost::asio::io_service io;
 auto systemBus = std::make_shared<sdbusplus::asio::connection>(io);
 auto objServer = sdbusplus::asio::object_server(systemBus);
@@ -115,6 +119,27 @@
         "/sys/bus/i2c/devices/i2c-" + std::to_string(bus) + "/mux_device"));
 }
 
+static void makeProbeInterface(size_t bus, size_t address)
+{
+    if (isMuxBus(bus))
+    {
+        return; // the mux buses are random, no need to publish
+    }
+    auto [it, success] = foundDevices.emplace(
+        std::make_pair(bus, address),
+        objServer.add_interface(
+            "/xyz/openbmc_project/FruDevice/" + std::to_string(bus) + "_" +
+                std::to_string(address),
+            "xyz.openbmc_project.Inventory.Item.I2CDevice"));
+    if (!success)
+    {
+        return; // already added
+    }
+    it->second->register_property("Bus", bus);
+    it->second->register_property("Address", address);
+    it->second->initialize();
+}
+
 static int isDevice16Bit(int file)
 {
     /* Get first byte */
@@ -413,6 +438,8 @@
                           << "\n";
             }
 
+            makeProbeInterface(bus, ii);
+
             /* Check for Device type if it is 8 bit or 16 bit */
             int flag = isDevice16Bit(file);
             if (flag < 0)
@@ -1118,6 +1145,12 @@
         }
 
         busmap.clear();
+        for (auto& [pair, interface] : foundDevices)
+        {
+            objServer.remove_interface(interface);
+        }
+        foundDevices.clear();
+
         auto scan =
             std::make_shared<FindDevicesWithCallback>(i2cBuses, busmap, [&]() {
                 for (auto& busIface : dbusInterfaceMap)