Sensor list time improvements

A lot inefficient code was added since these commands
were originally implemented. Fix the caches and add yield
method calls where calls were expensive.

Tested: ipmitool sensor list for 104 sensors was 18 seconds
over lan

Change-Id: I9ec2d42303839257629001f4cbb5cc1417989754
Signed-off-by: James Feist <james.feist@linux.intel.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index f6e5034..46cb8e8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,6 +8,9 @@
 set (CMAKE_CXX_STANDARD_REQUIRED ON)
 set (CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake ${CMAKE_MODULE_PATH})
 
+option (USING_ENTITY_MANAGER_DECORATORS
+        "Enable using EM decorators to map FRUs to entity IDs" ON)
+
 set (
     CMAKE_CXX_FLAGS
     "${CMAKE_CXX_FLAGS} \
@@ -118,4 +121,6 @@
     $<$<BOOL:${BMC_VALIDATION_UNSECURE_FEATURE}>:
     -DBMC_VALIDATION_UNSECURE_FEATURE>
     $<$<BOOL:${MDR_V1_SUPPORT}>: -DMDR_V1_SUPPORT>
+    $<$<BOOL:${USING_ENTITY_MANAGER_DECORATORS}>:
+    -DUSING_ENTITY_MANAGER_DECORATORS>
 )
diff --git a/include/storagecommands.hpp b/include/storagecommands.hpp
index c42f158..8516a9d 100644
--- a/include/storagecommands.hpp
+++ b/include/storagecommands.hpp
@@ -117,9 +117,10 @@
 {
 
 constexpr const size_t type12Count = 2;
-ipmi_ret_t getFruSdrs(size_t index, get_sdr::SensorDataFruRecord& resp);
+ipmi_ret_t getFruSdrs(ipmi::Context::ptr ctx, size_t index,
+                      get_sdr::SensorDataFruRecord& resp);
 
-ipmi_ret_t getFruSdrCount(size_t& count);
+ipmi_ret_t getFruSdrCount(ipmi::Context::ptr ctx, size_t& count);
 
 std::vector<uint8_t> getType12SDRs(uint16_t index, uint16_t recordId);
 } // namespace storage
diff --git a/src/sensorcommands.cpp b/src/sensorcommands.cpp
index efd31fa..d500a00 100644
--- a/src/sensorcommands.cpp
+++ b/src/sensorcommands.cpp
@@ -48,8 +48,7 @@
     std::map<sdbusplus::message::object_path,
              std::map<std::string, std::map<std::string, DbusVariant>>>;
 
-static constexpr int sensorListUpdatePeriod = 10;
-static constexpr int sensorMapUpdatePeriod = 2;
+static constexpr int sensorMapUpdatePeriod = 10;
 
 constexpr size_t maxSDRTotalSize =
     76; // Largest SDR Record Size (type 01) + SDR Overheader Size
@@ -210,7 +209,8 @@
     }
 }
 
-static bool getSensorMap(std::string sensorConnection, std::string sensorPath,
+static bool getSensorMap(boost::asio::yield_context yield,
+                         std::string sensorConnection, std::string sensorPath,
                          SensorMap &sensorMap)
 {
     static boost::container::flat_map<
@@ -232,22 +232,16 @@
         updateTimeMap[sensorConnection] = now;
 
         std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
-        auto managedObj = dbus->new_method_call(
-            sensorConnection.c_str(), "/", "org.freedesktop.DBus.ObjectManager",
-            "GetManagedObjects");
-
-        ManagedObjectType managedObjects;
-        try
-        {
-            auto reply = dbus->call(managedObj);
-            reply.read(managedObjects);
-        }
-        catch (sdbusplus::exception_t &)
+        boost::system::error_code ec;
+        auto managedObjects = dbus->yield_method_call<ManagedObjectType>(
+            yield, ec, sensorConnection.c_str(), "/",
+            "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+        if (ec)
         {
             phosphor::logging::log<phosphor::logging::level::ERR>(
-                "Error getting managed objects from connection",
-                phosphor::logging::entry("CONNECTION=%s",
-                                         sensorConnection.c_str()));
+                "GetMangagedObjects for getSensorMap failed",
+                phosphor::logging::entry("ERROR=%s", ec.message().c_str()));
+
             return false;
         }
 
@@ -402,7 +396,7 @@
 }
 
 ipmi::RspType<uint8_t, uint8_t, uint8_t, std::optional<uint8_t>>
-    ipmiSenGetSensorReading(uint8_t sensnum)
+    ipmiSenGetSensorReading(boost::asio::yield_context yield, uint8_t sensnum)
 {
     std::string connection;
     std::string path;
@@ -414,7 +408,7 @@
     }
 
     SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
+    if (!getSensorMap(yield, connection, path, sensorMap))
     {
         return ipmi::responseResponseError();
     }
@@ -523,13 +517,13 @@
  *  @returns IPMI completion code
  */
 ipmi::RspType<> ipmiSenSetSensorThresholds(
-    uint8_t sensorNum, bool lowerNonCriticalThreshMask,
-    bool lowerCriticalThreshMask, bool lowerNonRecovThreshMask,
-    bool upperNonCriticalThreshMask, bool upperCriticalThreshMask,
-    bool upperNonRecovThreshMask, uint2_t reserved, uint8_t lowerNonCritical,
-    uint8_t lowerCritical, uint8_t lowerNonRecoverable,
-    uint8_t upperNonCritical, uint8_t upperCritical,
-    uint8_t upperNonRecoverable)
+    boost::asio::yield_context yield, uint8_t sensorNum,
+    bool lowerNonCriticalThreshMask, bool lowerCriticalThreshMask,
+    bool lowerNonRecovThreshMask, bool upperNonCriticalThreshMask,
+    bool upperCriticalThreshMask, bool upperNonRecovThreshMask,
+    uint2_t reserved, uint8_t lowerNonCritical, uint8_t lowerCritical,
+    uint8_t lowerNonRecoverable, uint8_t upperNonCritical,
+    uint8_t upperCritical, uint8_t upperNonRecoverable)
 {
     constexpr uint8_t thresholdMask = 0xFF;
 
@@ -561,7 +555,7 @@
         return ipmi::response(status);
     }
     SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
+    if (!getSensorMap(yield, connection, path, sensorMap))
     {
         return ipmi::responseResponseError();
     }
@@ -750,7 +744,8 @@
               uint8_t, // upperNC
               uint8_t, // upperCrit
               uint8_t> // upperNRecoverable
-    ipmiSenGetSensorThresholds(uint8_t sensorNumber)
+    ipmiSenGetSensorThresholds(boost::asio::yield_context yield,
+                               uint8_t sensorNumber)
 {
     std::string connection;
     std::string path;
@@ -762,7 +757,7 @@
     }
 
     SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
+    if (!getSensorMap(yield, connection, path, sensorMap))
     {
         return ipmi::responseResponseError();
     }
@@ -832,7 +827,8 @@
               uint8_t, // assertionEnabledMsb
               uint8_t, // deassertionEnabledLsb
               uint8_t> // deassertionEnabledMsb
-    ipmiSenGetSensorEventEnable(uint8_t sensorNum)
+    ipmiSenGetSensorEventEnable(boost::asio::yield_context yield,
+                                uint8_t sensorNum)
 {
     std::string connection;
     std::string path;
@@ -850,7 +846,7 @@
     }
 
     SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
+    if (!getSensorMap(yield, connection, path, sensorMap))
     {
         return ipmi::responseResponseError();
     }
@@ -926,7 +922,8 @@
               std::bitset<16>, // assertions
               std::bitset<16>  // deassertion
               >
-    ipmiSenGetSensorEventStatus(uint8_t sensorNum)
+    ipmiSenGetSensorEventStatus(boost::asio::yield_context yield,
+                                uint8_t sensorNum)
 {
     if (sensorNum == 0xFF)
     {
@@ -945,7 +942,7 @@
     }
 
     SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
+    if (!getSensorMap(yield, connection, path, sensorMap))
     {
         phosphor::logging::log<phosphor::logging::level::ERR>(
             "ipmiSenGetSensorEventStatus: Sensor Mapping Error",
@@ -1072,7 +1069,7 @@
               uint32_t, // most recent erase
               uint8_t   // operationSupport
               >
-    ipmiStorageGetSDRRepositoryInfo(void)
+    ipmiStorageGetSDRRepositoryInfo(ipmi::Context::ptr ctx)
 {
     constexpr const uint16_t unspecifiedFreeSpace = 0xFFFF;
     if (sensorTree.empty() && !getSensorSubtree(sensorTree))
@@ -1081,7 +1078,7 @@
     }
 
     size_t fruCount = 0;
-    ipmi::Cc ret = ipmi::storage::getFruSdrCount(fruCount);
+    ipmi::Cc ret = ipmi::storage::getFruSdrCount(ctx, fruCount);
     if (ret != ipmi::ccSuccess)
     {
         return ipmi::response(ret);
@@ -1149,8 +1146,8 @@
 ipmi::RspType<uint16_t,            // next record ID
               std::vector<uint8_t> // payload
               >
-    ipmiStorageGetSDR(uint16_t reservationID, uint16_t recordID, uint8_t offset,
-                      uint8_t bytesToRead)
+    ipmiStorageGetSDR(ipmi::Context::ptr ctx, uint16_t reservationID,
+                      uint16_t recordID, uint8_t offset, uint8_t bytesToRead)
 {
     constexpr uint16_t lastRecordIndex = 0xFFFF;
 
@@ -1167,7 +1164,7 @@
     }
 
     size_t fruCount = 0;
-    ipmi::Cc ret = ipmi::storage::getFruSdrCount(fruCount);
+    ipmi::Cc ret = ipmi::storage::getFruSdrCount(ctx, fruCount);
     if (ret != ipmi::ccSuccess)
     {
         return ipmi::response(ret);
@@ -1217,7 +1214,7 @@
             {
                 return ipmi::responseInvalidFieldRequest();
             }
-            ret = ipmi::storage::getFruSdrs(fruIndex, data);
+            ret = ipmi::storage::getFruSdrs(ctx, fruIndex, data);
             if (ret != IPMI_CC_OK)
             {
                 return ipmi::response(ret);
@@ -1255,7 +1252,7 @@
     }
 
     SensorMap sensorMap;
-    if (!getSensorMap(connection, path, sensorMap))
+    if (!getSensorMap(ctx->yield, connection, path, sensorMap))
     {
         return ipmi::responseResponseError();
     }
diff --git a/src/storagecommands.cpp b/src/storagecommands.cpp
index 7b41d8d..f398980 100644
--- a/src/storagecommands.cpp
+++ b/src/storagecommands.cpp
@@ -27,6 +27,7 @@
 #include <functional>
 #include <iostream>
 #include <ipmid/api.hpp>
+#include <ipmid/message.hpp>
 #include <phosphor-ipmi-host/selutility.hpp>
 #include <phosphor-logging/log.hpp>
 #include <sdbusplus/message/types.hpp>
@@ -103,7 +104,8 @@
     "xyz.openbmc_project.FruDevice";
 constexpr static const char* entityManagerServiceName =
     "xyz.openbmc_project.EntityManager";
-constexpr static const size_t cacheTimeoutSeconds = 10;
+constexpr static const size_t cacheTimeoutSeconds = 30;
+constexpr static const size_t writeTimeoutSeconds = 10;
 
 // event direction is bit[7] of eventType where 1b = Deassertion event
 constexpr static const uint8_t deassertionEvent = 0x80;
@@ -112,8 +114,14 @@
 static uint8_t cacheBus = 0xFF;
 static uint8_t cacheAddr = 0XFF;
 
+static uint8_t writeBus = 0xFF;
+static uint8_t writeAddr = 0XFF;
+
+std::unique_ptr<phosphor::Timer> writeTimer = nullptr;
 std::unique_ptr<phosphor::Timer> cacheTimer = nullptr;
 
+ManagedObjectType frus;
+
 // we unfortunately have to build a map of hashes in case there is a
 // collision to verify our dev-id
 boost::container::flat_map<uint8_t, std::pair<uint8_t, uint8_t>> deviceHashes;
@@ -122,11 +130,15 @@
 
 bool writeFru()
 {
+    if (writeBus == 0xFF && writeAddr == 0xFF)
+    {
+        return true;
+    }
     std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
     sdbusplus::message::message writeFru = dbus->new_method_call(
         fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
         "xyz.openbmc_project.FruDeviceManager", "WriteFru");
-    writeFru.append(cacheBus, cacheAddr, fruCache);
+    writeFru.append(writeBus, writeAddr, fruCache);
     try
     {
         sdbusplus::message::message writeFruResp = dbus->call(writeFru);
@@ -138,18 +150,19 @@
             "error writing fru");
         return false;
     }
+    writeBus = 0xFF;
+    writeAddr = 0xFF;
     return true;
 }
 
-void createTimer()
+void createTimers()
 {
-    if (cacheTimer == nullptr)
-    {
-        cacheTimer = std::make_unique<phosphor::Timer>(writeFru);
-    }
+
+    writeTimer = std::make_unique<phosphor::Timer>(writeFru);
+    cacheTimer = std::make_unique<phosphor::Timer>([]() { return; });
 }
 
-ipmi_ret_t replaceCacheFru(uint8_t devId)
+ipmi::Cc replaceCacheFru(ipmi::Context::ptr ctx, uint8_t devId)
 {
     static uint8_t lastDevId = 0xFF;
 
@@ -162,24 +175,23 @@
     else if (timerRunning)
     {
         cacheTimer->stop();
-        writeFru();
     }
 
-    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
-    sdbusplus::message::message getObjects = dbus->new_method_call(
-        fruDeviceServiceName, "/", "org.freedesktop.DBus.ObjectManager",
-        "GetManagedObjects");
-    ManagedObjectType frus;
-    try
-    {
-        sdbusplus::message::message resp = dbus->call(getObjects);
-        resp.read(frus);
-    }
-    catch (sdbusplus::exception_t&)
+    cacheTimer->start(std::chrono::duration_cast<std::chrono::microseconds>(
+        std::chrono::seconds(cacheTimeoutSeconds)));
+
+    boost::system::error_code ec;
+
+    frus = ctx->bus->yield_method_call<ManagedObjectType>(
+        ctx->yield, ec, fruDeviceServiceName, "/",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+    if (ec)
     {
         phosphor::logging::log<phosphor::logging::level::ERR>(
-            "replaceCacheFru: error getting managed objects");
-        return IPMI_CC_RESPONSE_ERROR;
+            "GetMangagedObjects for getSensorMap failed",
+            phosphor::logging::entry("ERROR=%s", ec.message().c_str()));
+
+        return ipmi::ccResponseError;
     }
 
     deviceHashes.clear();
@@ -245,27 +257,29 @@
     }
 
     fruCache.clear();
-    sdbusplus::message::message getRawFru = dbus->new_method_call(
-        fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
-        "xyz.openbmc_project.FruDeviceManager", "GetRawFru");
+    ec.clear();
+
     cacheBus = deviceFind->second.first;
     cacheAddr = deviceFind->second.second;
-    getRawFru.append(cacheBus, cacheAddr);
-    try
+
+    fruCache = ctx->bus->yield_method_call<std::vector<uint8_t>>(
+        ctx->yield, ec, fruDeviceServiceName, "/xyz/openbmc_project/FruDevice",
+        "xyz.openbmc_project.FruDeviceManager", "GetRawFru", cacheBus,
+        cacheAddr);
+    if (ec)
     {
-        sdbusplus::message::message getRawResp = dbus->call(getRawFru);
-        getRawResp.read(fruCache);
-    }
-    catch (sdbusplus::exception_t&)
-    {
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "Couldn't get raw fru",
+            phosphor::logging::entry("ERROR=%s", ec.message().c_str()));
+
         lastDevId = 0xFF;
         cacheBus = 0xFF;
         cacheAddr = 0xFF;
-        return IPMI_CC_RESPONSE_ERROR;
+        return ipmi::ccResponseError;
     }
 
     lastDevId = devId;
-    return IPMI_CC_OK;
+    return ipmi::ccSuccess;
 }
 
 /** @brief implements the read FRU data command
@@ -279,15 +293,15 @@
 ipmi::RspType<uint8_t,             // Count
               std::vector<uint8_t> // Requested data
               >
-    ipmiStorageReadFruData(uint8_t fruDeviceId, uint16_t fruInventoryOffset,
-                           uint8_t countToRead)
+    ipmiStorageReadFruData(ipmi::Context::ptr ctx, uint8_t fruDeviceId,
+                           uint16_t fruInventoryOffset, uint8_t countToRead)
 {
     if (fruDeviceId == 0xFF)
     {
         return ipmi::responseInvalidFieldRequest();
     }
 
-    ipmi::Cc status = replaceCacheFru(fruDeviceId);
+    ipmi::Cc status = replaceCacheFru(ctx, fruDeviceId);
 
     if (status != ipmi::ccSuccess)
     {
@@ -327,7 +341,8 @@
  *   - countWritten  - Count written
  */
 ipmi::RspType<uint8_t>
-    ipmiStorageWriteFruData(uint8_t fruDeviceId, uint16_t fruInventoryOffset,
+    ipmiStorageWriteFruData(ipmi::Context::ptr ctx, uint8_t fruDeviceId,
+                            uint16_t fruInventoryOffset,
                             std::vector<uint8_t>& dataToWrite)
 {
     if (fruDeviceId == 0xFF)
@@ -337,7 +352,7 @@
 
     size_t writeLen = dataToWrite.size();
 
-    ipmi::Cc status = replaceCacheFru(fruDeviceId);
+    ipmi::Cc status = replaceCacheFru(ctx, fruDeviceId);
     if (status != ipmi::ccSuccess)
     {
         return ipmi::response(status);
@@ -379,10 +394,13 @@
         }
     }
     uint8_t countWritten = 0;
+
+    writeBus = cacheBus;
+    writeAddr = cacheAddr;
     if (atEnd)
     {
         // cancel timer, we're at the end so might as well send it
-        cacheTimer->stop();
+        writeTimer->stop();
         if (!writeFru())
         {
             return ipmi::responseInvalidFieldRequest();
@@ -391,11 +409,10 @@
     }
     else
     {
-        // start a timer, if no further data is sent in cacheTimeoutSeconds
-        // seconds, check to see if it is valid
-        createTimer();
-        cacheTimer->start(std::chrono::duration_cast<std::chrono::microseconds>(
-            std::chrono::seconds(cacheTimeoutSeconds)));
+        // start a timer, if no further data is sent  to check to see if it is
+        // valid
+        writeTimer->start(std::chrono::duration_cast<std::chrono::microseconds>(
+            std::chrono::seconds(writeTimeoutSeconds)));
         countWritten = 0;
     }
 
@@ -411,14 +428,14 @@
  */
 ipmi::RspType<uint16_t, // inventorySize
               uint8_t>  // accessType
-    ipmiStorageGetFruInvAreaInfo(uint8_t fruDeviceId)
+    ipmiStorageGetFruInvAreaInfo(ipmi::Context::ptr ctx, uint8_t fruDeviceId)
 {
     if (fruDeviceId == 0xFF)
     {
         return ipmi::responseInvalidFieldRequest();
     }
 
-    ipmi::Cc status = replaceCacheFru(fruDeviceId);
+    ipmi::Cc status = replaceCacheFru(ctx, fruDeviceId);
 
     if (status != IPMI_CC_OK)
     {
@@ -431,9 +448,9 @@
     return ipmi::responseSuccess(fruCache.size(), accessType);
 }
 
-ipmi_ret_t getFruSdrCount(size_t& count)
+ipmi_ret_t getFruSdrCount(ipmi::Context::ptr ctx, size_t& count)
 {
-    ipmi_ret_t ret = replaceCacheFru(0);
+    ipmi_ret_t ret = replaceCacheFru(ctx, 0);
     if (ret != IPMI_CC_OK)
     {
         return ret;
@@ -442,9 +459,10 @@
     return IPMI_CC_OK;
 }
 
-ipmi_ret_t getFruSdrs(size_t index, get_sdr::SensorDataFruRecord& resp)
+ipmi_ret_t getFruSdrs(ipmi::Context::ptr ctx, size_t index,
+                      get_sdr::SensorDataFruRecord& resp)
 {
-    ipmi_ret_t ret = replaceCacheFru(0); // this will update the hash list
+    ipmi_ret_t ret = replaceCacheFru(ctx, 0); // this will update the hash list
     if (ret != IPMI_CC_OK)
     {
         return ret;
@@ -457,21 +475,6 @@
     uint8_t& bus = device->second.first;
     uint8_t& address = device->second.second;
 
-    ManagedObjectType frus;
-
-    std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
-    sdbusplus::message::message getObjects = dbus->new_method_call(
-        fruDeviceServiceName, "/", "org.freedesktop.DBus.ObjectManager",
-        "GetManagedObjects");
-    try
-    {
-        sdbusplus::message::message resp = dbus->call(getObjects);
-        resp.read(frus);
-    }
-    catch (sdbusplus::exception_t&)
-    {
-        return IPMI_CC_RESPONSE_ERROR;
-    }
     boost::container::flat_map<std::string, DbusVariant>* fruData = nullptr;
     auto fru =
         std::find_if(frus.begin(), frus.end(),
@@ -506,74 +509,73 @@
         return IPMI_CC_RESPONSE_ERROR;
     }
 
+#ifdef USING_ENTITY_MANAGER_DECORATORS
+
     boost::container::flat_map<std::string, DbusVariant>* entityData = nullptr;
-    ManagedObjectType entities;
 
-    try
+    // todo: this should really use caching, this is a very inefficient lookup
+    boost::system::error_code ec;
+    ManagedObjectType entities = ctx->bus->yield_method_call<ManagedObjectType>(
+        ctx->yield, ec, entityManagerServiceName, "/",
+        "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+
+    if (ec)
     {
-        std::shared_ptr<sdbusplus::asio::connection> dbus = getSdBus();
+        phosphor::logging::log<phosphor::logging::level::ERR>(
+            "GetMangagedObjects for getSensorMap failed",
+            phosphor::logging::entry("ERROR=%s", ec.message().c_str()));
 
-        sdbusplus::message::message getObjects = dbus->new_method_call(
-            entityManagerServiceName, "/", "org.freedesktop.DBus.ObjectManager",
-            "GetManagedObjects");
+        return ipmi::ccResponseError;
+    }
 
-        sdbusplus::message::message resp = dbus->call(getObjects);
-        resp.read(entities);
-
-        auto entity = std::find_if(
-            entities.begin(), entities.end(),
-            [bus, address, &entityData](ManagedEntry& entry) {
-                auto findFruDevice = entry.second.find(
-                    "xyz.openbmc_project.Inventory.Decorator.FruDevice");
-                if (findFruDevice == entry.second.end())
-                {
-                    return false;
-                }
-
-                // Integer fields added via Entity-Manager json are uint64_ts by
-                // default.
-                auto findBus = findFruDevice->second.find("Bus");
-                auto findAddress = findFruDevice->second.find("Address");
-
-                if (findBus == findFruDevice->second.end() ||
-                    findAddress == findFruDevice->second.end())
-                {
-                    return false;
-                }
-                if ((std::get<uint64_t>(findBus->second) != bus) ||
-                    (std::get<uint64_t>(findAddress->second) != address))
-                {
-                    return false;
-                }
-
-                // At this point we found the device entry and should return
-                // true.
-                auto findIpmiDevice = entry.second.find(
-                    "xyz.openbmc_project.Inventory.Decorator.Ipmi");
-                if (findIpmiDevice != entry.second.end())
-                {
-                    entityData = &(findIpmiDevice->second);
-                }
-
-                return true;
-            });
-
-        if (entity == entities.end())
-        {
-            if constexpr (DEBUG)
+    auto entity = std::find_if(
+        entities.begin(), entities.end(),
+        [bus, address, &entityData](ManagedEntry& entry) {
+            auto findFruDevice = entry.second.find(
+                "xyz.openbmc_project.Inventory.Decorator.FruDevice");
+            if (findFruDevice == entry.second.end())
             {
-                std::fprintf(stderr, "Ipmi or FruDevice Decorator interface "
-                                     "not found for Fru\n");
+                return false;
             }
+
+            // Integer fields added via Entity-Manager json are uint64_ts by
+            // default.
+            auto findBus = findFruDevice->second.find("Bus");
+            auto findAddress = findFruDevice->second.find("Address");
+
+            if (findBus == findFruDevice->second.end() ||
+                findAddress == findFruDevice->second.end())
+            {
+                return false;
+            }
+            if ((std::get<uint64_t>(findBus->second) != bus) ||
+                (std::get<uint64_t>(findAddress->second) != address))
+            {
+                return false;
+            }
+
+            // At this point we found the device entry and should return
+            // true.
+            auto findIpmiDevice = entry.second.find(
+                "xyz.openbmc_project.Inventory.Decorator.Ipmi");
+            if (findIpmiDevice != entry.second.end())
+            {
+                entityData = &(findIpmiDevice->second);
+            }
+
+            return true;
+        });
+
+    if (entity == entities.end())
+    {
+        if constexpr (DEBUG)
+        {
+            std::fprintf(stderr, "Ipmi or FruDevice Decorator interface "
+                                 "not found for Fru\n");
         }
     }
-    catch (const std::exception& e)
-    {
-        std::fprintf(
-            stderr,
-            "Search for FruDevice+Ipmi Decorator Interface excepted: '%s'\n",
-            e.what());
-    }
+
+#endif
 
     std::string name;
     auto findProductName = fruData->find("BOARD_PRODUCT_NAME");
@@ -612,6 +614,7 @@
     uint8_t entityID = 0;
     uint8_t entityInstance = 0x1;
 
+#ifdef USING_ENTITY_MANAGER_DECORATORS
     if (entityData)
     {
         auto entityIdProperty = entityData->find("EntityId");
@@ -628,6 +631,7 @@
                 std::get<uint64_t>(entityInstanceProperty->second));
         }
     }
+#endif
 
     resp.body.entityID = entityID;
     resp.body.entityInstance = entityInstance;
@@ -1173,6 +1177,7 @@
 
 void registerStorageFunctions()
 {
+    createTimers();
     // <Get FRU Inventory Area Info>
     ipmi::registerHandler(ipmi::prioOemBase, ipmi::netFnStorage,
                           ipmi::storage::cmdGetFruInventoryAreaInfo,