Fixes bug in association based discovery

'''
 NSMD responds to mctpd interface added signal and query mctpReactor service for associations interface. Due to race condition call to fetch associations get failed and discovery also fails.

 With this commit interface added signal from mctpd and mctpReactor service will be considered for disccovery. Whichever comes later will trigger device discovery in case of device going online.
'''

Fixes nvbug https://nvbugspro.nvidia.com/bug/5752715
signed-off-by: <ayushkumart@nvidia.com>
diff --git a/common/utils.cpp b/common/utils.cpp
index 4d4df49..9c42655 100644
--- a/common/utils.cpp
+++ b/common/utils.cpp
@@ -54,14 +54,30 @@
     auto currentBinding = std::get<1>(currentMctpInfo);
     auto newBinding = std::get<1>(newMctpInfo);
 
-    if (mediumPriority.at(currentMedium) == mediumPriority.at(newMedium))
+    // Helper lambda to safely get priority with default for unknown keys
+    constexpr int defaultPriority = INT_MIN;
+
+    auto getMediumPriority = [](const MctpMedium& medium) {
+        auto it = mediumPriority.find(medium);
+        return (it != mediumPriority.end()) ? it->second : defaultPriority;
+    };
+
+    auto getBindingPriority = [](const MctpBinding& binding) {
+        auto it = bindingPriority.find(binding);
+        return (it != bindingPriority.end()) ? it->second : defaultPriority;
+    };
+
+    int currentMediumPri = getMediumPriority(currentMedium);
+    int newMediumPri = getMediumPriority(newMedium);
+
+    if (currentMediumPri == newMediumPri)
     {
-        return bindingPriority.at(currentBinding) >=
-               bindingPriority.at(newBinding);
+        return getBindingPriority(currentBinding) >=
+               getBindingPriority(newBinding);
     }
     else
     {
-        return mediumPriority.at(currentMedium) >= mediumPriority.at(newMedium);
+        return currentMediumPri >= newMediumPri;
     }
 }
 
diff --git a/meson.build b/meson.build
index 0e231d7..1568a5f 100644
--- a/meson.build
+++ b/meson.build
@@ -156,6 +156,13 @@
     )
 endif
 
+if get_option('enable-association-discovery').enabled()
+    add_project_arguments(
+        '-DENABLE_ASSOCIATION_DISCOVERY',
+        language: ['cpp', 'c'],
+    )
+endif
+
 if get_option('enable-pcie-aer-error').enabled() and not cx8_features
     add_project_arguments('-DENABLE_PCIE_AER_ERROR', language: ['cpp', 'c'])
 endif
diff --git a/meson_options.txt b/meson_options.txt
index 93c51fc..ab8b5fc 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -473,4 +473,11 @@
     type: 'feature',
     description: 'Enable Network Adapter write protection sensor/object',
     value: 'disabled',
+)
+
+option(
+    'enable-association-discovery',
+    type: 'feature',
+    description: 'Enable support for MCTP Reactor association based discovery',
+    value: 'disabled'
 )
\ No newline at end of file
diff --git a/nsmd/nsmDevice.cpp b/nsmd/nsmDevice.cpp
index fc866e7..d01e4f2 100644
--- a/nsmd/nsmDevice.cpp
+++ b/nsmd/nsmDevice.cpp
@@ -476,11 +476,22 @@
                                            std::string& mctpBinding)
 {
     bool isPreferred = true;
-    if (this->uuid.size() > 0)
+    try
     {
-        isPreferred = utils::isPreferred(
-            std::make_tuple(this->mctpMedium, this->mctpBinding),
-            std::make_tuple(mctpMedium, mctpBinding));
+        if (this->uuid.size() > 0)
+        {
+            isPreferred = utils::isPreferred(
+                std::make_tuple(this->mctpMedium, this->mctpBinding),
+                std::make_tuple(mctpMedium, mctpBinding));
+        }
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "NsmDevice::updateDiscoveryIdentifiers failed, eid={EID} uuid={UUID} mctpMedium={MCTP_MEDIUM} mctpBinding={MCTP_BINDING} error={ERROR}",
+            "EID", eid, "UUID", uuid, "MCTP_MEDIUM", mctpMedium, "MCTP_BINDING",
+            mctpBinding, "ERROR", e.what());
+        return false;
     }
 
     if (isPreferred)
diff --git a/requester/mctp_endpoint_discovery.cpp b/requester/mctp_endpoint_discovery.cpp
index ce6fb00..ee421ff 100644
--- a/requester/mctp_endpoint_discovery.cpp
+++ b/requester/mctp_endpoint_discovery.cpp
@@ -262,16 +262,400 @@
     co_return NSM_SW_SUCCESS;
 }
 
+#ifdef ENABLE_ASSOCIATION_DISCOVERY
+
+requester::Coroutine
+    MctpDiscovery::readMctpProperties(const std::string& objPath,
+                                      MctpInfos& mctpInfos)
+{
+    dbus::Interfaces interfaces{mctpEndpointIntfName};
+    dbus::PropertyMap allProperties;
+    try
+    {
+        auto mapperResponse = co_await utils::coGetServiceMap(objPath,
+                                                              interfaces);
+        if (mapperResponse.size() == 0)
+        {
+            lg2::error(
+                "readMctpProperties: coGetServiceMap failed for PATH={OBJ_PATH}",
+                "OBJ_PATH", objPath);
+            co_return NSM_SW_ERROR;
+        }
+        std::string service = mapperResponse.begin()->first;
+        lg2::info("service of PATH={OBJ_PATH} is {SERVICE}", "OBJ_PATH",
+                  objPath, "SERVICE", service);
+        allProperties = co_await utils::coGetAllDbusProperty(service, objPath);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "readMctpProperties: failed to get MctpInfo from PATH={OBJ_PATH},{ERROR}",
+            "OBJ_PATH", objPath, "ERROR", e);
+        co_return NSM_SW_ERROR;
+    }
+
+    uint8_t eid{};
+    std::string connectivity{};
+    uint32_t networkId{};
+    std::string mediumType{};
+    std::string uuid{};
+    std::string bindingType{};
+    std::vector<uint8_t> mctpTypes{};
+
+    if (allProperties.contains("EID"))
+    {
+        eid = std::get<uint8_t>(allProperties.at("EID"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: EID property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if constexpr (FILTER_MCTP_EID)
+    {
+        // MCTP EID 0 is a special Null EID as per MCTP DMTF
+        // specification doc
+        if (eid == MCTP_EID_TO_FILTER)
+        {
+            lg2::error(
+                "readMctpProperties: EID {EID}==MCTP_EID_TO_FILTER for PATH={OBJ_PATH}",
+                "EID", eid, "OBJ_PATH", objPath);
+            co_return NSM_SW_ERROR;
+        }
+    }
+    if (allProperties.contains("Connectivity"))
+    {
+        connectivity = std::get<std::string>(allProperties.at("Connectivity"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: Connectivity property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("NetworkId"))
+    {
+        networkId = std::get<uint32_t>(allProperties.at("NetworkId"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: NetworkId property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("MediumType"))
+    {
+        mediumType = std::get<std::string>(allProperties.at("MediumType"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: MediumType property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        // Not a mandatory property as per upstream guidelines
+    }
+
+    if (allProperties.contains("UUID"))
+
+    {
+        uuid = std::get<std::string>(allProperties.at("UUID"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: UUID property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("BindingType"))
+    {
+        bindingType = std::get<std::string>(allProperties.at("BindingType"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: BindingType property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        // Not a mandatory property as per upstream guidelines
+    }
+    if (allProperties.contains("SupportedMessageTypes"))
+    {
+        mctpTypes = std::get<std::vector<uint8_t>>(
+            allProperties.at("SupportedMessageTypes"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: SupportedMessageTypes property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    MctpInfo mctpInfo = std::make_tuple(eid, uuid, mediumType, networkId,
+                                        bindingType,
+                                        (connectivity == "Available"), objPath);
+    cachedMctpInfoByPath[objPath] = mctpInfo;
+    if (connectivity == "Available")
+    {
+        if (std::find(mctpTypes.begin(), mctpTypes.end(), mctpTypeVDM) !=
+            mctpTypes.end())
+        {
+            mctpInfos.push_back(mctpInfo);
+        }
+        else
+        {
+            lg2::info(
+                "readMctpProperties: mctpTypeVDM command not supported for PATH={OBJ_PATH}",
+                "OBJ_PATH", objPath);
+        }
+    }
+    else
+    {
+        mctpInfos.push_back(mctpInfo);
+    }
+    co_return NSM_SW_SUCCESS;
+}
+
 requester::Coroutine
     MctpDiscovery::handleDiscoverEndpoints(sdbusplus::message::message& msg,
                                            MctpInfos& mctpInfos)
 {
-    constexpr std::string_view mctpEndpointIntfName{
-        "xyz.openbmc_project.MCTP.Endpoint"};
-
     sdbusplus::message::object_path objPath;
     dbus::InterfaceMap interfaces;
     msg.read(objPath, interfaces);
+    if (interfaces.find(std::string(mctpEndpointIntfName)) != interfaces.end())
+    {
+        populateMctpInfo(interfaces, objPath.str, mctpInfos);
+    }
+    else
+    {
+        handleMctpStateTransition(objPath);
+        co_await readMctpProperties(objPath.str, mctpInfos);
+    }
+
+    // watch PropertiesChanged signal from au.com.codeconstruct.MCTP.Endpoint1
+    // PDI
+    if (enableMatches.find(objPath.str) == enableMatches.end())
+    {
+        enableMatches.emplace(
+            objPath.str,
+            sdbusplus::bus::match_t(
+                bus,
+                sdbusplus::bus::match::rules::propertiesChanged(
+                    objPath.str, "au.com.codeconstruct.MCTP.Endpoint1"),
+                std::bind_front(&MctpDiscovery::refreshEndpoints, this)));
+    }
+    co_return NSM_SW_SUCCESS;
+}
+
+void MctpDiscovery::discoverEndpoints(sdbusplus::message::message& msg)
+{
+    sdbusplus::message::object_path objPath;
+    dbus::InterfaceMap interfaces;
+    msg.read(objPath, interfaces);
+    sd_bus_message_rewind(msg.get(), true);
+
+    if (interfaces.find(std::string(mctpEndpointIntfName)) !=
+            interfaces.end() ||
+        interfaces.find(std::string(associationIntfName)) != interfaces.end())
+    {
+        std::string foundIntf = interfaces.find(std::string(
+                                    mctpEndpointIntfName)) != interfaces.end()
+                                    ? mctpEndpointIntfName
+                                    : associationIntfName;
+
+        lg2::info(
+            "MctpDiscovery: Recieved InterfacesAdded signal for objPath={OBJ_PATH} and interface = {INTF}",
+            "OBJ_PATH", objPath.str, "INTF", foundIntf);
+        mctpQueuedSignals[objPath.str].emplace(msg);
+        requester::Coroutine::assign(deviceStateChangeTaskHandles[objPath.str],
+                                     [&, objPath]() -> requester::Coroutine {
+            // coverity[missing_return]
+            co_return co_await deviceStateChangeTask(objPath.str);
+        });
+    }
+}
+
+#else
+
+requester::Coroutine
+    MctpDiscovery::readMctpProperties(const std::string& objPath,
+                                      MctpInfos& mctpInfos)
+{
+    dbus::Interfaces interfaces{mctpEndpointIntfName};
+    dbus::PropertyMap allProperties;
+    try
+    {
+        auto mapperResponse = co_await utils::coGetServiceMap(objPath,
+                                                              interfaces);
+        if (mapperResponse.size() == 0)
+        {
+            lg2::error(
+                "readMctpProperties: coGetServiceMap failed for PATH={OBJ_PATH}",
+                "OBJ_PATH", objPath);
+            co_return NSM_SW_ERROR;
+        }
+        std::string service = mapperResponse.begin()->first;
+        lg2::info("service of PATH={OBJ_PATH} is {SERVICE}", "OBJ_PATH",
+                  objPath, "SERVICE", service);
+        allProperties = co_await utils::coGetAllDbusProperty(service, objPath);
+    }
+    catch (const std::exception& e)
+    {
+        lg2::error(
+            "readMctpProperties: failed to get MctpInfo from PATH={OBJ_PATH},{ERROR}",
+            "OBJ_PATH", objPath, "ERROR", e);
+        co_return NSM_SW_ERROR;
+    }
+
+    uint8_t eid{};
+    std::string connectivity{};
+    uint32_t networkId{};
+    std::string mediumType{};
+    std::string uuid{};
+    std::string bindingType{};
+    std::vector<uint8_t> mctpTypes{};
+
+    if (allProperties.contains("EID"))
+    {
+        eid = std::get<uint8_t>(allProperties.at("EID"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: EID property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if constexpr (FILTER_MCTP_EID)
+    {
+        // MCTP EID 0 is a special Null EID as per MCTP DMTF
+        // specification doc
+        if (eid == MCTP_EID_TO_FILTER)
+        {
+            lg2::error(
+                "readMctpProperties: EID {EID}==MCTP_EID_TO_FILTER for PATH={OBJ_PATH}",
+                "EID", eid, "OBJ_PATH", objPath);
+            co_return NSM_SW_ERROR;
+        }
+    }
+    if (allProperties.contains("Connectivity"))
+    {
+        connectivity = std::get<std::string>(allProperties.at("Connectivity"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: Connectivity property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("NetworkId"))
+    {
+        networkId = std::get<uint32_t>(allProperties.at("NetworkId"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: NetworkId property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("MediumType"))
+    {
+        mediumType = std::get<std::string>(allProperties.at("MediumType"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: MediumType property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("UUID"))
+
+    {
+        uuid = std::get<std::string>(allProperties.at("UUID"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: UUID property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    if (allProperties.contains("BindingType"))
+    {
+        bindingType = std::get<std::string>(allProperties.at("BindingType"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: BindingType property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+    if (allProperties.contains("SupportedMessageTypes"))
+    {
+        mctpTypes = std::get<std::vector<uint8_t>>(
+            allProperties.at("SupportedMessageTypes"));
+    }
+    else
+    {
+        lg2::error(
+            "readMctpProperties: SupportedMessageTypes property not found for PATH={OBJ_PATH}",
+            "OBJ_PATH", objPath);
+        co_return NSM_ERR_INVALID_DATA;
+    }
+
+    MctpInfo mctpInfo = std::make_tuple(eid, uuid, mediumType, networkId,
+                                        bindingType,
+                                        (connectivity == "Available"), objPath);
+
+    cachedMctpInfoByPath[objPath] = mctpInfo;
+
+    if (connectivity == "Available")
+    {
+        if (std::find(mctpTypes.begin(), mctpTypes.end(), mctpTypeVDM) !=
+            mctpTypes.end())
+        {
+            mctpInfos.push_back(mctpInfo);
+        }
+        else
+        {
+            lg2::info(
+                "readMctpProperties: mctpTypeVDM command not supported for PATH={OBJ_PATH}",
+                "OBJ_PATH", objPath);
+        }
+    }
+    else
+    {
+        mctpInfos.push_back(mctpInfo);
+    }
+    co_return NSM_SW_SUCCESS;
+}
+
+requester::Coroutine
+    MctpDiscovery::handleDiscoverEndpoints(sdbusplus::message::message& msg,
+                                           MctpInfos& mctpInfos)
+{
+    sdbusplus::message::object_path objPath;
+    dbus::InterfaceMap interfaces;
+    msg.read(objPath, interfaces);
+
     populateMctpInfo(interfaces, objPath.str, mctpInfos);
 
     // watch PropertiesChanged signal from au.com.codeconstruct.MCTP.Endpoint1
@@ -299,8 +683,8 @@
     if (interfaces.find(std::string(mctpEndpointIntfName)) != interfaces.end())
     {
         lg2::info(
-            "MctpDiscovery: Recieved InterfacesAdded signal for objPath={OBJ_PATH}",
-            "OBJ_PATH", objPath.str);
+            "MctpDiscovery: Recieved InterfacesAdded signal for objPath={OBJ_PATH} and interface = {INTF}",
+            "OBJ_PATH", objPath.str, "INTF", mctpEndpointIntfName);
         mctpQueuedSignals[objPath.str].emplace(msg);
         requester::Coroutine::assign(deviceStateChangeTaskHandles[objPath.str],
                                      [&, objPath]() -> requester::Coroutine {
@@ -310,6 +694,8 @@
     }
 }
 
+#endif
+
 requester::Coroutine
     MctpDiscovery::handleRefreshEndpoints(sdbusplus::message::message& msg,
                                           MctpInfos& mctpInfos)
@@ -329,100 +715,8 @@
             "Processing au.com.codeconstruct.MCTP.Endpoint1 propertiesChanged signal for "
             "Connectivity=={CONN} at PATH={OBJ_PATH} from sender={SENDER}",
             "CONN", connectivity, "OBJ_PATH", objPath, "SENDER", sender);
-        handleMctpStateTransition(objPath, (connectivity == "Available"));
-        try
-        {
-            dbus::Interfaces interfaces{"xyz.openbmc_project.MCTP.Endpoint"};
-            auto mapperResponse = co_await utils::coGetServiceMap(objPath,
-                                                                  interfaces);
-            if (mapperResponse.size() == 0)
-            {
-                lg2::error(
-                    "handleRefreshEndpoints: coGetServiceMap failed for PATH={OBJ_PATH}",
-                    "OBJ_PATH", objPath);
-                co_return NSM_SW_ERROR;
-            }
-            std::string service = mapperResponse.begin()->first;
-            lg2::info("service of PATH={OBJ_PATH} is {SERVICE}", "OBJ_PATH",
-                      objPath, "SERVICE", service);
-            allProperties = co_await utils::coGetAllDbusProperty(service,
-                                                                 objPath);
-        }
-        catch (const std::exception& e)
-        {
-            lg2::error(
-                "handleRefreshEndpoints: failed to get MctpInfo from PATH={OBJ_PATH},{ERROR}",
-                "OBJ_PATH", objPath, "ERROR", e);
-            co_return NSM_SW_ERROR;
-        }
-
-        uint8_t eid{};
-        uint32_t networkId{};
-        std::string mediumType{};
-        std::string uuid{};
-        std::string bindingType{};
-        std::vector<uint8_t> mctpTypes{};
-
-        if (allProperties.contains("EID"))
-        {
-            eid = std::get<uint8_t>(allProperties.at("EID"));
-        }
-        if constexpr (FILTER_MCTP_EID)
-        {
-            // MCTP EID 0 is a special Null EID as per MCTP DMTF
-            // specification doc
-            if (eid == MCTP_EID_TO_FILTER)
-            {
-                co_return NSM_SW_ERROR;
-            }
-        }
-
-        if (allProperties.contains("NetworkId"))
-        {
-            networkId = std::get<uint32_t>(allProperties.at("NetworkId"));
-        }
-        if (allProperties.contains("MediumType"))
-        {
-            mediumType = std::get<std::string>(allProperties.at("MediumType"));
-        }
-        if (allProperties.contains("UUID"))
-
-        {
-            uuid = std::get<std::string>(allProperties.at("UUID"));
-        }
-        if (allProperties.contains("BindingType"))
-        {
-            bindingType =
-                std::get<std::string>(allProperties.at("BindingType"));
-        }
-        if (allProperties.contains("SupportedMessageTypes"))
-        {
-            mctpTypes = std::get<std::vector<uint8_t>>(
-                allProperties.at("SupportedMessageTypes"));
-        }
-
-        MctpInfo mctpInfo =
-            std::make_tuple(eid, uuid, mediumType, networkId, bindingType,
-                            (connectivity == "Available"), objPath);
-        cachedMctpInfoByPath[objPath] = mctpInfo;
-        if (connectivity == "Available")
-        {
-            if (std::find(mctpTypes.begin(), mctpTypes.end(), mctpTypeVDM) !=
-                mctpTypes.end())
-            {
-                mctpInfos.push_back(mctpInfo);
-            }
-            else
-            {
-                lg2::info(
-                    "handleRefreshEndpoints: mctpTypeVDM command not supported for PATH={OBJ_PATH}",
-                    "OBJ_PATH", objPath);
-            }
-        }
-        else
-        {
-            mctpInfos.push_back(mctpInfo);
-        }
+        handleMctpStateTransition(objPath);
+        co_await readMctpProperties(objPath, mctpInfos);
     }
     co_return NSM_SW_SUCCESS;
 }
@@ -477,6 +771,38 @@
     co_return NSM_SW_SUCCESS;
 }
 
+#ifdef ENABLE_ASSOCIATION_DISCOVERY
+void MctpDiscovery::cleanEndpoints(
+    [[maybe_unused]] sdbusplus::message::message& msg)
+{
+    sdbusplus::message::object_path objPath;
+    std::vector<std::string> interfaces;
+    msg.read(objPath, interfaces);
+    sd_bus_message_rewind(msg.get(), true);
+    if (std::find(interfaces.begin(), interfaces.end(),
+                  std::string(mctpEndpointIntfName)) != interfaces.end() ||
+        std::find(interfaces.begin(), interfaces.end(),
+                  std::string(associationIntfName)) != interfaces.end())
+    {
+        std::string foundIntf = std::find(interfaces.begin(), interfaces.end(),
+                                          std::string(mctpEndpointIntfName)) !=
+                                        interfaces.end()
+                                    ? mctpEndpointIntfName
+                                    : associationIntfName;
+        lg2::info(
+            "MctpDiscovery: Recieved InterfacesRemoved signal for objPath={OBJ_PATH} intf = {INTF}",
+            "OBJ_PATH", objPath.str, "INTF", foundIntf);
+        mctpQueuedSignals[objPath.str].emplace(msg);
+        requester::Coroutine::assign(deviceStateChangeTaskHandles[objPath.str],
+                                     [&, objPath]() -> requester::Coroutine {
+            // coverity[missing_return]
+            co_return co_await deviceStateChangeTask(objPath.str);
+        });
+    }
+}
+
+#else
+
 void MctpDiscovery::cleanEndpoints(
     [[maybe_unused]] sdbusplus::message::message& msg)
 {
@@ -488,8 +814,8 @@
                   std::string(mctpEndpointIntfName)) != interfaces.end())
     {
         lg2::info(
-            "MctpDiscovery: Recieved InterfacesRemoved signal for objPath={OBJ_PATH}",
-            "OBJ_PATH", objPath.str);
+            "MctpDiscovery: Recieved InterfacesRemoved signal for objPath={OBJ_PATH} intf = {INTF}",
+            "OBJ_PATH", objPath.str, "INTF", mctpEndpointIntfName);
         mctpQueuedSignals[objPath.str].emplace(msg);
         requester::Coroutine::assign(deviceStateChangeTaskHandles[objPath.str],
                                      [&, objPath]() -> requester::Coroutine {
@@ -499,6 +825,8 @@
     }
 }
 
+#endif
+
 requester::Coroutine
     MctpDiscovery::SendRecvNsmMsg(eid_t eid, Request& request,
                                   std::shared_ptr<const nsm_msg>& responseMsg,
@@ -627,7 +955,17 @@
                     eid) // check if nsmDevice is not changed with new EID
                          // during setOnline
                 {
-                    nsmDevice->finishDeviceDiscovery();
+                    if (perEidQueuedMctpInfos[eid].size() == 1)
+                    {
+                        nsmDevice->finishDeviceDiscovery();
+                    }
+                    else
+                    {
+                        lg2::info(
+                            "coSetdeviceStateOnlineTask : signal still in queue for eid= {EID}, marking device as discovery pending",
+                            "EID", eid);
+                        nsmDevice->initDeviceDiscovery();
+                    }
                 }
             }
         }
@@ -755,10 +1093,11 @@
     co_return NSM_SW_SUCCESS;
 }
 
-requester::Coroutine
-    MctpDiscovery::findConfiguredAssociations(const std::string& objPath,
-                                              std::string& configuredPath)
+requester::Coroutine MctpDiscovery::findConfiguredAssociations(
+    [[maybe_unused]] const std::string& objPath,
+    [[maybe_unused]] std::string& configuredPath)
 {
+#ifdef ENABLE_ASSOCIATION_DISCOVERY
     dbus::Interfaces interfaces{"xyz.openbmc_project.Association.Definitions"};
     try
     {
@@ -812,6 +1151,7 @@
         lg2::error("Error while finding configured associations.", "ERROR", e);
         co_return NSM_SW_ERROR;
     }
+#endif
     co_return NSM_SW_SUCCESS;
 }
 
@@ -1095,8 +1435,7 @@
     return ret;
 }
 
-void MctpDiscovery::handleMctpStateTransition(const std::string objPath,
-                                              [[maybe_unused]] const bool state)
+void MctpDiscovery::handleMctpStateTransition(const std::string objPath)
 {
     eid_t eid = 0;
     size_t lastSlash = objPath.rfind('/');
diff --git a/requester/mctp_endpoint_discovery.hpp b/requester/mctp_endpoint_discovery.hpp
index 5ca91f5..05398b4 100644
--- a/requester/mctp_endpoint_discovery.hpp
+++ b/requester/mctp_endpoint_discovery.hpp
@@ -17,6 +17,8 @@
 
 #pragma once
 
+#include "config.h"
+
 #include "common/types.hpp"
 #include "nsmd/nsmDevice.hpp"
 #include "nsmd/socket_handler.hpp"
@@ -27,7 +29,7 @@
 #include <filesystem>
 #include <initializer_list>
 #include <vector>
-
+// # define ENABLE_ASSOCIATION_DISCOVERY
 namespace mctp
 {
 
@@ -120,6 +122,9 @@
     std::map<std::string, std::coroutine_handle<>> deviceStateChangeTaskHandles;
     requester::Coroutine deviceStateChangeTask(const std::string path);
 
+    requester::Coroutine readMctpProperties(const std::string& objPath,
+                                            MctpInfos& mctpInfos);
+
     void discoverEndpoints(sdbusplus::message::message& msg);
     requester::Coroutine
         handleDiscoverEndpoints(sdbusplus::message::message& msg,
@@ -160,6 +165,8 @@
     const std::string mctpEndpointIntfName{"xyz.openbmc_project.MCTP.Endpoint"};
 
     const std::string mctpBindingIntfName{"xyz.openbmc_project.MCTP.Binding"};
+    const std::string associationIntfName{
+        "xyz.openbmc_project.Association.Definitions"};
 
     /** @brief UUID interface name */
     static constexpr std::string_view uuidEndpointIntfName{
@@ -226,11 +233,10 @@
                              bool active, MctpMedium mctpMedium,
                              MctpBinding mctpBinding);
     int mapMctpEIDForNsmDevice(std::shared_ptr<nsm::NsmDevice> nsmDevice);
-    void handleMctpStateTransition(const std::string objPath,
-                                   [[maybe_unused]] const bool state);
-    requester::Coroutine
-        findConfiguredAssociations(const std::string& objPath,
-                                   ConfiguredPath& configuredPath);
+    void handleMctpStateTransition(const std::string objPath);
+    requester::Coroutine findConfiguredAssociations(
+        [[maybe_unused]] const std::string& objPath,
+        [[maybe_unused]] ConfiguredPath& configuredPath);
 };
 
 } // namespace mctp