hwmontempsensor: Move instantiateDevices
Move instantiateDevices to DeviceMgmt.hpp as a template function.
This way other sensors can leverage this functionality.
Tested:
Same hwmon temp devices are getting instantiated.
Change-Id: I5d932ea57fa67809232a92fc769cd66a17a0cc70
Signed-off-by: Matt Simmering <matthew.simmering@intel.com>
diff --git a/src/DeviceMgmt.hpp b/src/DeviceMgmt.hpp
index c8c76f1..170cd37 100644
--- a/src/DeviceMgmt.hpp
+++ b/src/DeviceMgmt.hpp
@@ -62,3 +62,83 @@
setupPropertiesChangedMatches(
sdbusplus::asio::connection& bus, const I2CDeviceTypeMap& typeMap,
const std::function<void(sdbusplus::message_t&)>& handler);
+
+// returns a {path: <I2CDevice, is_new>} map. is_new indicates if the I2CDevice
+// is newly instantiated by this call (true) or was already there (false).
+template <class T>
+boost::container::flat_map<std::string,
+ std::pair<std::shared_ptr<I2CDevice>, bool>>
+ instantiateDevices(
+ const ManagedObjectType& sensorConfigs,
+ const boost::container::flat_map<std::string, std::shared_ptr<T>>&
+ sensors,
+ const I2CDeviceTypeMap& sensorTypes)
+{
+ boost::container::flat_map<std::string,
+ std::pair<std::shared_ptr<I2CDevice>, bool>>
+ devices;
+ for (const auto& [path, sensor] : sensorConfigs)
+ {
+ for (const auto& [name, cfg] : sensor)
+ {
+ PowerState powerState = getPowerState(cfg);
+ if (!readingStateGood(powerState))
+ {
+ continue;
+ }
+
+ auto findSensorName = cfg.find("Name");
+ if (findSensorName == cfg.end())
+ {
+ continue;
+ }
+ std::string sensorName =
+ std::get<std::string>(findSensorName->second);
+
+ auto findSensor = sensors.find(sensorName);
+ if (findSensor != sensors.end() && findSensor->second != nullptr &&
+ findSensor->second->isActive())
+ {
+ devices.emplace(
+ path.str,
+ std::make_pair(findSensor->second->getI2CDevice(), false));
+ continue;
+ }
+
+ std::optional<I2CDeviceParams> params =
+ getI2CDeviceParams(sensorTypes, cfg);
+ if (params.has_value() && !params->deviceStatic())
+ {
+ // There exist error cases in which a sensor device that we
+ // need is already instantiated, but needs to be destroyed and
+ // re-created in order to be useful (for example if we crash
+ // after instantiating a device and the sensor device's power
+ // is cut before we get restarted, leaving it "present" but
+ // not really usable). To be on the safe side, instantiate a
+ // temporary device that's immediately destroyed so as to
+ // ensure that we end up with a fresh instance of it.
+ if (params->devicePresent())
+ {
+ std::cerr << "Clearing out previous instance for "
+ << path.str << "\n";
+ I2CDevice tmp(*params);
+ }
+
+ try
+ {
+ devices.emplace(
+ path.str,
+ std::make_pair(std::make_shared<I2CDevice>(*params),
+ true));
+ }
+ catch (std::runtime_error&)
+ {
+ std::cerr << "Failed to instantiate " << params->type->name
+ << " at address " << params->address << " on bus "
+ << params->bus << "\n";
+ }
+ }
+ }
+ }
+ return devices;
+}