1 #include "associations.hpp"
2 
3 void removeAssociation(const std::string& sourcePath, const std::string& owner,
4                        sdbusplus::asio::object_server& server,
5                        AssociationOwnersType& assocOwners,
6                        AssociationInterfaces& assocInterfaces)
7 {
8     // Use associationOwners to find the association paths and endpoints
9     // that the passed in object path and service own.  Remove all of
10     // these endpoints from the actual association D-Bus objects, and if
11     // the endpoints property is then empty, the whole association object
12     // can be removed.  Note there can be multiple services that own an
13     // association, and also that sourcePath is the path of the object
14     // that contains the org.openbmc.Associations interface and not the
15     // association path itself.
16 
17     // Find the services that have associations for this object path
18     auto owners = assocOwners.find(sourcePath);
19     if (owners == assocOwners.end())
20     {
21         return;
22     }
23 
24     // Find the association paths and endpoints owned by this object
25     // path for this service.
26     auto assocs = owners->second.find(owner);
27     if (assocs == owners->second.end())
28     {
29         return;
30     }
31 
32     for (const auto& [assocPath, endpointsToRemove] : assocs->second)
33     {
34         removeAssociationEndpoints(server, assocPath, endpointsToRemove,
35                                    assocInterfaces);
36     }
37 
38     // Remove the associationOwners entries for this owning path/service.
39     owners->second.erase(assocs);
40     if (owners->second.empty())
41     {
42         assocOwners.erase(owners);
43     }
44 }
45 
46 void removeAssociationEndpoints(
47     sdbusplus::asio::object_server& objectServer, const std::string& assocPath,
48     const boost::container::flat_set<std::string>& endpointsToRemove,
49     AssociationInterfaces& assocInterfaces)
50 {
51     auto assoc = assocInterfaces.find(assocPath);
52     if (assoc == assocInterfaces.end())
53     {
54         return;
55     }
56 
57     auto& endpointsInDBus = std::get<endpointsPos>(assoc->second);
58 
59     for (const auto& endpointToRemove : endpointsToRemove)
60     {
61         auto e = std::find(endpointsInDBus.begin(), endpointsInDBus.end(),
62                            endpointToRemove);
63 
64         if (e != endpointsInDBus.end())
65         {
66             endpointsInDBus.erase(e);
67         }
68     }
69 
70     if (endpointsInDBus.empty())
71     {
72         objectServer.remove_interface(std::get<ifacePos>(assoc->second));
73         std::get<ifacePos>(assoc->second) = nullptr;
74         std::get<endpointsPos>(assoc->second).clear();
75     }
76     else
77     {
78         std::get<ifacePos>(assoc->second)
79             ->set_property("endpoints", endpointsInDBus);
80     }
81 }
82