CpuSensor: Fallback to ping if no presence sensor

Not all cpus have presence, add a fallback method of
exposing the item interface.

Tested: After power on, the interface was available

Change-Id: Ia3ee7ec309f31d5cf769f9582b091905f541cd40
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp
index a595236..0e6f99d 100644
--- a/src/CPUSensorMain.cpp
+++ b/src/CPUSensorMain.cpp
@@ -53,6 +53,9 @@
 static constexpr bool DEBUG = false;
 
 boost::container::flat_map<std::string, std::unique_ptr<CPUSensor>> gCpuSensors;
+boost::container::flat_map<std::string,
+                           std::shared_ptr<sdbusplus::asio::dbus_interface>>
+    inventoryIfaces;
 
 enum State
 {
@@ -111,7 +114,18 @@
         if (cpu.state != State::OFF)
         {
             available = true;
-            break;
+            std::shared_ptr<sdbusplus::asio::dbus_interface> iface =
+                inventoryIfaces[cpu.name];
+            if (iface != nullptr)
+            {
+                continue;
+            }
+            iface = objectServer.add_interface(
+                cpuInventoryPath + std::string("/") + cpu.name,
+                "xyz.openbmc_project.Inventory.Item");
+            iface->register_property("PrettyName", cpu.name);
+            iface->register_property("Present", true);
+            iface->initialize();
         }
     }
     if (!available)
@@ -329,7 +343,10 @@
                               << sensorName << "\n";
                 }
             }
-            gCpuSensors[sensorName] = std::make_unique<CPUSensor>(
+            auto& sensorPtr = gCpuSensors[sensorName];
+            // make sure destructor fires before creating a new one
+            sensorPtr = nullptr;
+            sensorPtr = std::make_unique<CPUSensor>(
                 inputPathStr, sensorType, objectServer, dbusConnection, io,
                 sensorName, std::move(sensorThresholds), *interfacePath, cpuId,
                 show, dtsOffset);
@@ -542,14 +559,10 @@
     });
 }
 
-bool getCpuConfig(
-    const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
-    boost::container::flat_set<CPUConfig>& cpuConfigs,
-    ManagedObjectType& sensorConfigs,
-    sdbusplus::asio::object_server& objectServer,
-    boost::container::flat_map<
-        std::string, std::shared_ptr<sdbusplus::asio::dbus_interface>>&
-        inventoryIfaces)
+bool getCpuConfig(const std::shared_ptr<sdbusplus::asio::connection>& systemBus,
+                  boost::container::flat_set<CPUConfig>& cpuConfigs,
+                  ManagedObjectType& sensorConfigs,
+                  sdbusplus::asio::object_server& objectServer)
 {
     bool useCache = false;
     sensorConfigs.clear();
@@ -588,7 +601,8 @@
                 std::string name =
                     std::regex_replace(nameRaw, illegalDbusRegex, "_");
 
-                bool present = true;
+                auto present = std::optional<bool>();
+                // if we can't detect it via gpio, we set presence later
                 for (const SensorBaseConfiguration& suppConfig : sensor.second)
                 {
                     if (suppConfig.first.find("PresenceGpio") !=
@@ -599,20 +613,17 @@
                     }
                 }
 
-                if (inventoryIfaces.find(name) == inventoryIfaces.end())
+                if (inventoryIfaces.find(name) == inventoryIfaces.end() &&
+                    present)
                 {
                     auto iface = objectServer.add_interface(
                         cpuInventoryPath + std::string("/") + name,
                         "xyz.openbmc_project.Inventory.Item");
                     iface->register_property("PrettyName", name);
-                    iface->register_property("Present", present);
+                    iface->register_property("Present", *present);
                     iface->initialize();
                     inventoryIfaces[name] = std::move(iface);
                 }
-                if (!present)
-                {
-                    continue; // no reason to look for non present cpu
-                }
 
                 auto findBus = config.second.find("Bus");
                 if (findBus == config.second.end())
@@ -669,9 +680,6 @@
     boost::asio::deadline_timer creationTimer(io);
     boost::asio::deadline_timer filterTimer(io);
     ManagedObjectType sensorConfigs;
-    boost::container::flat_map<std::string,
-                               std::shared_ptr<sdbusplus::asio::dbus_interface>>
-        inventoryIfaces;
 
     filterTimer.expires_from_now(boost::posix_time::seconds(1));
     filterTimer.async_wait([&](const boost::system::error_code& ec) {
@@ -680,8 +688,7 @@
             return; // we're being canceled
         }
 
-        if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer,
-                         inventoryIfaces))
+        if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs, objectServer))
         {
             detectCpuAsync(pingTimer, creationTimer, io, objectServer,
                            systemBus, cpuConfigs, sensorConfigs);
@@ -710,7 +717,7 @@
                 }
 
                 if (getCpuConfig(systemBus, cpuConfigs, sensorConfigs,
-                                 objectServer, inventoryIfaces))
+                                 objectServer))
                 {
                     detectCpuAsync(pingTimer, creationTimer, io, objectServer,
                                    systemBus, cpuConfigs, sensorConfigs);