diff options
Diffstat (limited to 'src/associations.cpp')
-rw-r--r-- | src/associations.cpp | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/src/associations.cpp b/src/associations.cpp new file mode 100644 index 0000000..3ae7db4 --- /dev/null +++ b/src/associations.cpp @@ -0,0 +1,76 @@ +#include "associations.hpp" + +void removeAssociation(const std::string& sourcePath, const std::string& owner, + sdbusplus::asio::object_server& server, + AssociationOwnersType& assocOwners, + AssociationInterfaces& assocInterfaces) +{ + // Use associationOwners to find the association paths and endpoints + // that the passed in object path and service own. Remove all of + // these endpoints from the actual association D-Bus objects, and if + // the endpoints property is then empty, the whole association object + // can be removed. Note there can be multiple services that own an + // association, and also that sourcePath is the path of the object + // that contains the org.openbmc.Associations interface and not the + // association path itself. + + // Find the services that have associations for this object path + auto owners = assocOwners.find(sourcePath); + if (owners == assocOwners.end()) + { + return; + } + + // Find the association paths and endpoints owned by this object + // path for this service. + auto assocs = owners->second.find(owner); + if (assocs == owners->second.end()) + { + return; + } + + for (const auto& [assocPath, endpointsToRemove] : assocs->second) + { + // Get the association D-Bus object for this assocPath + auto target = assocInterfaces.find(assocPath); + if (target == assocInterfaces.end()) + { + continue; + } + + // Remove the entries in the endpoints D-Bus property for this + // path/owner/association-path. + auto& existingEndpoints = std::get<endpointsPos>(target->second); + for (const auto& endpointToRemove : endpointsToRemove) + { + auto e = std::find(existingEndpoints.begin(), + existingEndpoints.end(), endpointToRemove); + + if (e != existingEndpoints.end()) + { + existingEndpoints.erase(e); + } + } + + // Remove the association from D-Bus if there are no more endpoints, + // otherwise just update the endpoints property. + if (existingEndpoints.empty()) + { + server.remove_interface(std::get<ifacePos>(target->second)); + std::get<ifacePos>(target->second) = nullptr; + std::get<endpointsPos>(target->second).clear(); + } + else + { + std::get<ifacePos>(target->second) + ->set_property("endpoints", existingEndpoints); + } + } + + // Remove the associationOwners entries for this owning path/service. + owners->second.erase(assocs); + if (owners->second.empty()) + { + assocOwners.erase(owners); + } +} |